How do you convert a HttpPostedFileBase to an Image?
Asked Answered
U

2

52

I am using ASP.NET MVC and I've an action that uploads the file. The file is being uploaded properly. But I want width and height of the image. I think I need to convert the HttpPostedFileBase to Image first and then proceed. How do I do that?

And please let me know if there is another better way to get the width and height of the image.

Unbridled answered 23/7, 2009 at 13:24 Comment(0)
A
109

I use Image.FromStream to as follows:

Image.FromStream(httpPostedFileBase.InputStream, true, true)

Note that the returned Image is IDisposable.

You'll need a reference to System.Drawing.dll for this to work, and Image is in the System.Drawing namespace.

Resizing the Image

I'm not sure what you're trying to do, but if you happen to be making thumbnails or something similar, you may be interested in doing something like...

try {
    var bitmap = new Bitmap(newWidth,newHeight);
    using (Graphics g = Graphics.FromImage(bitmap)) {
        g.SmoothingMode = SmoothingMode.HighQuality;
        g.PixelOffsetMode = PixelOffsetMode.HighQuality;
        g.CompositingQuality = CompositingQuality.HighQuality;
        g.InterpolationMode = InterpolationMode.HighQualityBicubic;
        g.DrawImage(oldImage,
            new Rectangle(0,0,newWidth,newHeight),
            clipRectangle, GraphicsUnit.Pixel);
    }//done with drawing on "g"
    return bitmap;//transfer IDisposable ownership
} catch { //error before IDisposable ownership transfer
    if (bitmap != null) bitmap.Dispose();
    throw;
}

where clipRectangle is the rectangle of the original image you wish to scale into the new bitmap (you'll need to manually deal with aspect ratio). The catch-block is typical IDisposable usage inside a constructor; you maintain ownership of the new IDisposable object until it is returned (you may want to doc that with code-comments).

Saving as Jpeg

Unfortunately, the default "save as jpeg" encoder doesn't expose any quality controls, and chooses a terribly low default quality.

You can manually select the encoder as well, however, and then you can pass arbitrary parameters:

ImageCodecInfo jpgInfo = ImageCodecInfo.GetImageEncoders()
    .Where(codecInfo => codecInfo.MimeType == "image/jpeg").First();
using (EncoderParameters encParams = new EncoderParameters(1))
{
    encParams.Param[0] = new EncoderParameter(Encoder.Quality, (long)quality);
    //quality should be in the range [0..100]
    image.Save(outputStream, jpgInfo, encParams);
}
Abstractionist answered 23/7, 2009 at 13:28 Comment(11)
Great code snippet! Why are you disposing of the image in your catch block and then rethrowing the exception instead of just using the finally block?Induction
because the finally block always executes - but the newly created image only needs to be disposed on error. If no error occurs, the new image was correctly constructed and becomes owned by the calling function - now it's their responsibility to dispose it.Abstractionist
I'll add an explanation about the try-catch with IDisposable.Abstractionist
hi, sorry to bring this dead thread alive, was wondering, do u know how i can save the file to a file system? i didn't wanna use the dbase for saving it,just the url maybe. also, im trying to figure out if i want to adjust sizes to 50x100 when the image size is like 150x150.is it recommended to always set the w and h to those numbers or do i just proportionately adjust it meet the limit? thanks!Noel
This code simply scales the image - you'll need to decide how to crop (clipRectangle) and you'll want to ensure the resultant aspect ratio isn't too far off. To save to the filesystem, simply pass the appropriate stream (in the example, it's named outputStream) to the Save method.Abstractionist
When I use Image image = Image.FromStream(item.InputStream, true, true); code I get parameter is not valid exeption. Please tell me , How can i fixx this problem?Econometrics
@ElvinArzumanoğlu: you should probably ask a new question if you can't easily solve the problem, because in your own question you can add all the relevant details. But as a general tip; try saving the stream to disk and reproducing the exception locally from a file stream - if you can do that, you have a fairly small test case and those are always easier to deal with.Abstractionist
@Eamon,I am blocked for asking question,so I can't ask any question:(.at first my scenario is that I have a dropzone js library(dropzonejs.com/)for uploading image,what I can upload many images a time,I add these images to my httpPfile in this dropzone upload action and add this to Lis<>,,then I get this uploading files in save button,but in foreach loop when I write previous code I get parameter is not valid exeption,then i think this error means i can write this only first time in post action,then i try convert httpPoBase to image in dropezone action and so converting work fineEconometrics
I don't quite understand what you said, but httpPostedFileBase.InputStream is only valid in the request in which the file was posted - in that request you will need to save the data somewhere, and you probably want to do image processing right away too.Abstractionist
@EamonNerbonne below line of code is not working for me System.Drawing.Image sourceimage = System.Drawing.Image.FromStream(file.InputStream,true,true);Dobb
@HeemanshuBhalla: it's a standard function; so you might check the docs: msdn.microsoft.com/en-us/library/21zw9ah6 - or ask a new question with more details as to what isn't working.Abstractionist
A
7

If you are sure, that the source is image and doesn't need editing, you can do it easily as described here

[HttpPost]
public void Index(HttpPostedFileBase file)
{
    if (file.ContentLength > 0)
    {
        var filename = Path.GetFileName(file.FileName);

        System.Drawing.Image sourceimage =
            System.Drawing.Image.FromStream(file.InputStream);
    }
}

To secure the file is image, add javascript validation to View by adding accept attribute with MIME type to input tag

<input type="file" accept="image/*">

and jQuery validation script

$.validator.addMethod('accept', function () { return true; });

The whole solution can be found here

Anathema answered 20/11, 2013 at 11:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.