I have a simple MVC2 app that uploads a file from the browser to an MS SQL database as an Image blob.
Then I can return the results with something like:
public FileContentResult ShowPhoto(int id)
{
TemporaryImageUpload tempImageUpload = new TemporaryImageUpload();
tempImageUpload = _service.GetImageData(id) ?? null;
if (tempImageUpload != null)
{
byte[] byteArray = tempImageUpload.TempImageData;
return new FileContentResult (temp, "image/jpeg");
}
return null;
}
But I want to return these images resized as both thumbnails and as a gallery-sized view. Is this possible to do within this Result? I've been playing around with the great imageresizer.net but it seems to want to store the images on my server which I want to avoid. Is it possible to do this on the fly..?
I need to keep the original file and don't, if possible, want to store the images as files on the server.
Thanks for any pointers!
ImageResizer.NET allows you to pass a stream to it for resizing, see Managed API usage
The method you'd use is:
ImageResizer.ImageBuilder.Current.Build(object source, object dest, ResizeSettings settings)
I modified your method to go about it this way, but it is untested. Hope it helps.
public FileContentResult ShowPhoto(int id)
{
TemporaryImageUpload tempImageUpload = new TemporaryImageUpload();
tempImageUpload = _service.GetImageData(id) ?? null;
if (tempImageUpload != null)
{
byte[] byteArray = tempImageUpload.TempImageData;
using(var outStream = new MemoryStream()){
using(var inStream = new MemoryStream(byteArray)){
var settings = new ResizeSettings("maxwidth=200&maxheight=200");
ImageResizer.ImageBuilder.Current.Build(inStream, outStream, settings);
var outBytes = outStream.ToArray();
return new FileContentResult (outBytes, "image/jpeg");
}
}
}
return null;
}
There was a recent Hanselminutes podcast on Image Resizing with Nathanael Jones discussing some of the pitfalls of image resizing.
Even if you do not have 30 odd minutes to listen to the full podcast, the show notes point to some interesting resizing pitfalls, as well as an image resizing library also written by Nathanael Jones.
You could resize the image on the fly:
public void ResizeImage(Stream input, Stream output, int newWidth, int maxHeight)
{
using (var srcImage = Image.FromStream(input))
{
int newHeight = srcImage.Height * newWidth / srcImage.Width;
if (newHeight > maxHeight)
{
newWidth = srcImage.Width * maxHeight / srcImage.Height;
newHeight = maxHeight;
}
using (var newImage = new Bitmap(newWidth, newHeight))
using (var gr = Graphics.FromImage(newImage))
{
gr.SmoothingMode = SmoothingMode.AntiAlias;
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.PixelOffsetMode = PixelOffsetMode.HighQuality;
gr.DrawImage(srcImage, new Rectangle(0, 0, newWidth, newHeight));
newImage.Save(output, ImageFormat.Jpeg);
}
}
}
and then you could have 2 controller actions (one that displays the full image size and one that displays a thumbnail):
public ActionResult Thumbnail(int id)
{
var tempImageUpload = new TemporaryImageUpload();
tempImageUpload = _service.GetImageData(id) ?? null;
if (tempImageUpload == null)
{
return HttpNotFound();
}
using (var input = new MemoryStream(tempImageUpload.TempImageData))
using (var output = new MemoryStream())
{
ResizeImage(input, output, 640, 1000);
return File(output.ToArray(), "image/jpeg");
}
}
Related
I need to change the size of the photo and save it to a new size when the user selects a photo for the upload, before saving the photo.
i using this code but it not save with new size . whats the problem ?
public async Task<IActionResult> UploadNewsPic()
{
var file = Request.Form.Files[0];
try
{
if (file.Length > 0)
{
string fileName = ContentDispositionHeaderValue.Parse(file.ContentDisposition).FileName.Trim('"');
string fullPath = Path.Combine(_applicationRoot.UploadNewPath(), file.Name);
using (var stream = new FileStream(fullPath, FileMode.Create))
{
if (file.IsImage())
{
await file.ResizeImage(3, 3);
file.CopyTo(stream);
}
}
}
return Ok();
}
catch (Exception e)
{
return BadRequest();
}
}
and this is Resize Extention :
public async static Task<Image> ResizeImage(this IFormFile file, int width, int height)
{
using (var memoryStream = new MemoryStream())
{
await file.CopyToAsync(memoryStream);
using (var img = Image.FromStream(memoryStream))
{
return img.Resize(width, height);
}
}
}
public static Image Resize(this Image image, int width, int height)
{
var res = new Bitmap(width, height);
using (var graphic = Graphics.FromImage(res))
{
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(image, 0, 0, width, height);
}
return res;
}
You need to save the result from ResizeImage to the stream. Right now you are just copying the original file.
var img = await file.ResizeImage(3, 3);
img.Save(stream, SomeFormat);
Your ResizeImage() function return a resized image, it doesn't edit the image itself, so you must set it to a variable.
if (file.IsImage())
{
Image imageResized = await file.ResizeImage(3, 3);
// ...
}
I have a simple web application (ASP.NET MVC 5 C#) which allows users to upload several files (images actually).
Currently it works well, the images are stored into the data base and I can read them later.
But I want to resize the images before saving them into the db, since the user can upload extremely big images.
Here is my controller:
public ActionResult Create(Annonce annonce, IEnumerable<HttpPostedFileBase> photos)
{
if (ModelState.IsValid)
{
// Read each uploaded files and add if into the collection
foreach (HttpPostedFileBase fichier in photos)
{
if (fichier != null && fichier.ContentLength > 0)
{
// Making a new object
var photo = new Photo
{
FileName = System.IO.Path.GetFileName(fichier.FileName),
ContentType = fichier.ContentType
};
using (var reader = new System.IO.BinaryReader(fichier.InputStream))
{
photo.Content = reader.ReadBytes(fichier.ContentLength);
}
// Add the current image to the collection
annonce.Photos.Add(photo);
}
}
db.Annonces.Add(annonce);
db.SaveChanges();
return RedirectToAction("Details", new { id = annonce.ID });
}
return View(annonce);
}
How can I resize my images and still be able to save them into the db?
Is-it even possible?
Thanks!
This code will perform a high quality resizing.(means you wont lose very much)
public static Bitmap ResizeImage(Image image, int width, int height)
{
var destRect = new Rectangle(0, 0, width, height);
var destImage = new Bitmap(width, height);
destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);
using (var graphics = Graphics.FromImage(destImage))
{
graphics.CompositingMode = CompositingMode.SourceCopy;
graphics.CompositingQuality = CompositingQuality.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
using (var wrapMode = new ImageAttributes())
{
wrapMode.SetWrapMode(WrapMode.TileFlipXY);
graphics.DrawImage(image, destRect, 0, 0, image.Width,image.Height, GraphicsUnit.Pixel, wrapMode);
}
}
return destImage;
}
Call ResizeImage() and assign it to a bitmap which you'll insert into your database.goodluck
you can convert it to byte array and than store it in your db as byte type
public byte[] imageToByteArray(System.Drawing.Image imageIn)
{
MemoryStream ms = new MemoryStream();
imageIn.Save(ms,System.Drawing.Imaging.ImageFormat.Gif);
return ms.ToArray();
}
you can do the same but inverted to get it out and display it as image from the DB:
public Image byteArrayToImage(byte[] byteArrayIn)
{
MemoryStream ms = new MemoryStream(byteArrayIn);
Image returnImage = Image.FromStream(ms);
return returnImage;
}
You also approach to ImageResizer as link below:
http://www.c-sharpcorner.com/article/image-resize-in-asp-net-mvc-using-image-resizer/
I created a function to allow uploaded transparent .png files to be inserted into a SQL Server database and the displayed on a web page via an HttpHandler.
While this all works, the png transparency changes to black when it's viewed on the web page. Is there a way of preserving the transparency?
Here's my image service which inserts into the database from the MVC controller:
public void AddImage(int productId, string caption, byte[] bytesOriginal)
{
string jpgpattern = ".jpg|.JPG";
string pngpattern = ".png|.PNG";
string pattern = jpgpattern;
ImageFormat imgFormat = ImageFormat.Jpeg;
if (caption.ToLower().EndsWith(".png"))
{
imgFormat = ImageFormat.Png;
pattern = pngpattern;
}
ProductImage productImage = new ProductImage();
productImage.ProductId = productId;
productImage.BytesOriginal = bytesOriginal;
productImage.BytesFull = Helpers.ResizeImageFile(bytesOriginal, 600, imgFormat);
productImage.BytesPoster = Helpers.ResizeImageFile(bytesOriginal, 198, imgFormat);
productImage.BytesThumb = Helpers.ResizeImageFile(bytesOriginal, 100, imgFormat);
productImage.Caption = Common.RegexReplace(caption, pattern, "");
productImageDao.Insert(productImage);
}
And here's the "ResizeImageFile" helper function:
public static byte[] ResizeImageFile(byte[] imageFile, int targetSize, ImageFormat imageFormat)
{
using (System.Drawing.Image oldImage = System.Drawing.Image.FromStream(new MemoryStream(imageFile)))
{
Size newSize = CalculateDimensions(oldImage.Size, targetSize);
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
{
using (Graphics canvas = Graphics.FromImage(newImage))
{
canvas.SmoothingMode = SmoothingMode.AntiAlias;
canvas.InterpolationMode = InterpolationMode.HighQualityBicubic;
canvas.PixelOffsetMode = PixelOffsetMode.HighQuality;
canvas.DrawImage(oldImage, new Rectangle(new Point(0, 0), newSize));
MemoryStream m = new MemoryStream();
newImage.Save(m, imageFormat);
return m.GetBuffer();
}
}
}
}
What do I need to do to preserve the png transparency? Please show examples. I'm seriously not an expert with image manipulation.
Thanks.
Maybe try changing pixel format form PixelFormat.Format24bppRgb to PixelFormat.Format32bppRgb. You need the extra 8 bits to hold the alpha channel.
Using PixelFormat.Format32bppRgb didn't work for me. What worked however is using oldImage.PixelFormat when drawing the new image. So the corresponding line of code becomes:
using (Bitmap newImage = new Bitmap(newSize.Width, newSize.Height, oldImage.PixelFormat))
I am trying to make/use a smaller image than the one taken with the camera to display in parts of my program (due to memory issues...)
Unfortunately I don't seem to be able to find ways to make a smaller image/thumbnail on the mobile device - the way it is possible in normal windows...
Is there a way to make a smaller image on Win Mobile 6.5/Compact Framework?
For example - these do not work on Win Mobile
What is the "best" way to create a thumbnail using ASP.NET?
This looks promising - but i want to just put the image on a PictureBox - and not sure how to use this to make it work.
This code should be work. I have also implemented this code. For that I have used OpenNETCF.Drawing.dll.
barray = GetImage(filepath);
if (barray != null)
{
ms.Write(barray, 0, barray.Length - 1);
imageBitmap = CreateThumbnail(ms, new Size(PreviewImageWidth, PreviewImageHeight));
bm = ImageUtils.IBitmapImageToBitmap(imageBitmap);
// m_CurrentImageID = Convert.ToInt32(lstPic.ToList()[index].Id);
PictureBox ib = ((PictureBox)this.imagePanel.Controls[(nIndex * 2) + 1]);
ib.Image = bm;
}
private byte[] GetImage(string FilePath)
{
byte[] barray;
if (File.Exists(FilePath))
{
FileInfo _fileInfo = new FileInfo(FilePath);
long _NumBytes = _fileInfo.Length;
FileStream _FStream = new FileStream(FilePath, FileMode.Open, FileAccess.Read);
BinaryReader _BinaryReader = new BinaryReader(_FStream);
barray = _BinaryReader.ReadBytes(Convert.ToInt32(_NumBytes));
_FStream.Flush();
_FStream.Dispose();
return barray;
}
else
{
return null;
}
}
public IBitmapImage CreateThumbnail(Stream stream, Size size)
{
IBitmapImage imageBitmap;
ImageInfo ii;
IImage image;
ImagingFactory factory = new ImagingFactoryClass();
try
{
factory.CreateImageFromStream(new StreamOnFile(stream), out image);
image.GetImageInfo(out ii);
factory.CreateBitmapFromImage(image, (uint)size.Width, (uint)size.Height, ii.PixelFormat, InterpolationHint.InterpolationHintDefault, out imageBitmap);
return imageBitmap;
}
catch (Exception ex)
{
CreateLogFiles Err = new CreateLogFiles();
Err.ErrorLog(ex.Message);
return null;
}
finally
{
imageBitmap = null;
image = null;
factory = null;
}
}
This should work:
this.pictureBox1.Image = System.Drawing.Image.FromFile(#"\path to image").GetThumbnailImage(100, 100, null, IntPtr.Zero);
but the quality of thumbnail may not be as good. For quality thumbnail images you could refer to this post here
Could anyone tell me how I could retrieve an image or a thumbnail of a website through my ASP.NET application? I have seen this functionality in a few sites such as Alexa etc.
Try SnapCasa's free and easy to use service. Just form your image tag like this:
<img src="http://SnapCasa.com/Get.aspx?code=[code]&size=[size]&url=[url]" />
Requires sign-up, but it's free for 500,000 requests a month. [code] is an api key that they provide after sign-up. [size] is one of three sizes available. [url] is the website address to the site for which you want to display a thumbnail.
If you want to work with the image from your code, here are a couple of helper methods:
static public byte[] GetBytesFromUrl(string url)
{
byte[] b;
HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(url);
WebResponse myResp = myReq.GetResponse();
Stream stream = myResp.GetResponseStream();
//int i;
using (BinaryReader br = new BinaryReader(stream))
{
//i = (int)(stream.Length);
b = br.ReadBytes(500000);
br.Close();
}
myResp.Close();
return b;
}
static public void WriteBytesToFile(string fileName, byte[] content)
{
FileStream fs = new FileStream(fileName, FileMode.Create);
BinaryWriter w = new BinaryWriter(fs);
try
{
w.Write(content);
}
finally
{
fs.Close();
w.Close();
}
}
Then, in your code, just use:
//get byte array for image
var imageBytes = GetBytesFromUrl("http://SnapCasa.com/Get.aspx?code=[code]&size=[size]&url=[url]");
//save file to disk
WriteBytesToFile("c:\someImageFile.jpg", imageBytes);
Should be doable using a web-browser object and saving the view port to a bitmap resized to thumbnail.
I have not tested this code but try tweaking it after substituting for the thumbnail params.
using (WebBrowser wb = new WebBrowser()) {
wb.ScrollBarsEnabled = false;
wb.AllowNavigation = true;
wb.ScriptErrorsSuppressed = true;
wb.ClientSize = new Size(thumbInfo_viewportWidth, thumbInfo_viewportHeight);
if ((thumbInfo_Uri != null)) {
wb.Navigate(thumbInfo_Uri.AbsoluteUri);
} else {
wb.Navigate("about:blank");
HtmlDocument doc = wb.Document.OpenNew(true);
doc.Write(thumbInfo_HTML);
wb.Refresh(WebBrowserRefreshOption.Completely);
}
// create an image of the client area of the webbrowser control, than
// scale it down to the dimensions specified.
if ((wb.Document != null && wb.Document.Body != null)) {
Rectangle rec = default(Rectangle);
rec.Size = wb.ClientSize;
using (Bitmap fullSizeBitmap = new Bitmap(thumbInfo_viewportWidth, thumbInfo_viewportHeight)) {
wb.DrawToBitmap(fullSizeBitmap, wb.Bounds);
using (Bitmap scaledBitmap = new Bitmap(thumbInfo_width, thumbInfo_height)) {
using (Graphics gr = Graphics.FromImage(scaledBitmap)) {
gr.SmoothingMode = Drawing2D.SmoothingMode.HighQuality;
gr.CompositingQuality = Drawing2D.CompositingQuality.HighQuality;
gr.InterpolationMode = Drawing2D.InterpolationMode.High;
Rectangle rect = new Rectangle(0, 0, thumbInfo_width, thumbInfo_height);
gr.DrawImage(fullSizeBitmap, rect, 0, 0, rec.Size.Width, rec.Size.Height, GraphicsUnit.Pixel);
scaledBitmap.Save(thumbInfo_physicalPath);
}
}
}
}
}
One thing to note that it is an expensive process.