I have an Image file that I would like to crop and resize at the same time using the System.Drawing class
I am trying to build upon the ideas found in this article :http://www.schnieds.com/2011/07/image-upload-crop-and-resize-with.html
I am able to Crop and Resize seperately but when I try to combine the process, I am getting some strange output.
Here is what I have been trying
using (System.Drawing.Bitmap _bitmap = new System.Drawing.Bitmap(w, h))
{
_bitmap.SetResolution(img.HorizontalResolution, img.VerticalResolution);
using (Graphics _graphic = Graphics.FromImage(_bitmap))
{
_graphic.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
_graphic.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
_graphic.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;
_graphic.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
//Code used to crop
_graphic.DrawImage(img, 0, 0, w, h);
_graphic.DrawImage(img, new Rectangle(0, 0, w, h), x, y, w, h, GraphicsUnit.Pixel);
//Code I used to resize
_graphic.DrawImage(img, 0, 0, img.Width, img.Height);
_graphic.DrawImage(img, new Rectangle(0, 0, W_FixedSize, H_FixedSize), 0, 0, img.Width, img.Height, GraphicsUnit.Pixel);
//continued...
}
}
In the above code…there are two sections commented…one to crop and one one to resize.
For cropping, I pass in the proper coords and width/height part of the image to crop(x, y, w, h).
I would like to crop based on my parameters and draw the image based on the W_FixedSize and H_Fixed size params.
One thing all of the answers missed is that the resulting image will have a 50% transparent 1 pixel border around the image, due to a bug in GDI.
To properly crop and resize, you need to apply the following settings to the graphics object:
Then you need to make an ImageAttributes instance to fix the border bug:
Then, when calling DrawImage, pass
iaas the last parameter.If you’re dealing with any PNG, TIFF, or ICO images and converting them to a format that doesn’t support transparency, you also need to call g.Clear(bgcolor) prior to calling DrawImage.
If you’re encoding to jpeg format, make sure to set the Quality parameter and dispose of the EncoderParameters object afterwards.
The Bitmap instance that you are reading from will lock the underlying file until after it is disposed. If you use the FromStream method, you must keep the stream open until after the Bitmap instance is disposed. A good way to do this is clone the stream into a MemoryStream instance and assign it to the Bitmap.Tag property.
I have a more complete list of GDI+ cropping & resizing bugs to avoid on my blog.
I usually try to push people to use my imageresizing.net library, as it’s designed to operate safely on a website with optimum performance. 1 line of code, and very little room for user error.
I downloaded Schnieds’ example project, and I have to say it’s an (unnecessarily) complicated way of doing things. Non-destructive editing is actually much easier, as shown on this article. It’s easy to combine with Uploadify, although I don’t cover that on the blog.
Also, re-encoding the image during upload is very destructive, both for jpeg and png files. Validation is good, but just dispose the instance after validation, don’t re-encode it. Schnieds’ example also leaks memory through the undisposed Bitmap instance – running it on a high-volume server would crash it quickly.