In C# it can be tiresome to do certain image editing functions using GDI+. This post has some fun editing methods which can come in handy at times. I have also included a nice little C# program to show all the functionality of the methods below.
Saving a Jpeg
The first thing to do here is set up the method signature with the input
parameters. These are the save file path (string), the Image to save
(System.Drawing.Bitmap), and a quality setting (long).
private void saveJpeg(string path, Bitamp img, long quality)
The next few things to do are setting up encoder information for saving the file. This includes setting an EncoderParameter for the quality of the Jpeg. The next thing is to get the codec information from your computer for jpegs. I do this by having a function to loop through the available ones on the computer and making sure jpeg is there. The line under that makes sure that the jpeg codec was found on the computer. If not it just returns out of the method.
The last thing to do is save the bitmap using the codec and the encoder infomation.
private void saveJpeg(string path, Bitmap img, long quality)
{
// Encoder parameter for image quality
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, quality);
// Jpeg image codec
ImageCodecInfo jpegCodec = this.getEncoderInfo("image/jpeg");
if(jpegCodec == null)
return;
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(path, jpegCodec, encoderParams);
}
private ImageCodecInfo getEncoderInfo(string mimeType)
{
// Get image codecs for all image formats
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders();
// Find the correct image codec
for (int i = 0; i < codecs.Length; i++)
if (codecs[i].MimeType == mimeType)
return codecs[i];
return null;
}
Cropping
The method takes two objects - the image to crop (System.Drawing.Image)
and the rectangle to crop out (System.Drawing.Rectangle). The next thing
done is to create a Bitmap (System.Drawing.Bitmap) of the image. The
only thing left is to crop the image. This is done by cloning the
original image but only taking a rectangle of the original.
private static Image cropImage(Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
Bitmap bmpCrop = bmpImage.Clone(cropArea,
bmpImage.PixelFormat);
return (Image)(bmpCrop);
}
Resizing
This next set of code is a slightly longer and more complex. The main reason this code is longer is because this resize function will keep the height and width proportional.
To start with we see that the input parameters are the image to resize
(System.Drawing.Image) and the size (System.Drawing.Size). Also in this
set of code are a few variables we use. The first two are the source
height and width which is used later. And there are 3 other variables to
calculate the proportion information.
private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
}
The next step is to actually figure out what the size of the resized image should be. The first step is to calculate the percentages of the new size compared to the original. Next we need to decide which percentage is smaller because this is the percent of the original image we will use for both height and width. And now we calculate the number of height and width pixels for the destination image.
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
The final thing to do is create the bitmap (System.Drawing.Bitmap) which
we will draw the resized image on using a Graphics
(System.Drawing.Graphics) object. I also set the interpolation mode,
which is the algorithm used to resize the image. I prefer
HighQualityBicubic, which from my testing seems to return the highest
quality results. And just to clean up a little I dispose the Graphics
object.
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
And this gives us the final code.
private static Image resizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercent = 0;
float nPercentW = 0;
float nPercentH = 0;
nPercentW = ((float)size.Width / (float)sourceWidth);
nPercentH = ((float)size.Height / (float)sourceHeight);
if (nPercentH < nPercentW)
nPercent = nPercentH;
else
nPercent = nPercentW;
int destWidth = (int)(sourceWidth * nPercent);
int destHeight = (int)(sourceHeight * nPercent);
Bitmap b = new Bitmap(destWidth, destHeight);
Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(imgToResize, 0, 0, destWidth, destHeight);
g.Dispose();
return (Image)b;
}
Here is the source code and a C# VS2005 Express Edition solution with the needed methods and some test code.
Source Files:
Like the tutorial! Thanks :)
I want to process the *.img & *.tif format images by using the C# codings. Any body could you assit me?
Thankyou
Nice tutorial! But it would be nice to put up how to resize images without preserving the aspect ratio as well. I've been very bugged up over that. D=
I can answer that right here. To resize the image without preserving the aspect ratio just skip the ratio calculations. Just set
destWidthtosize.WidthanddestHeighttosize.Heightand you're all set.its really nice to see this example. i'm very thankfull to this code.
Thanks, thanks, thanks
Thankx.
finally i found what i looked...
Thanks
For resizing you can also use
Image.GetThumbnailImage.Image.GetThumbnailImagedoes not use interpolation when resizing, so loss of quality can be a concern. For quick resizing where quality is not important,GetThumbnailImageis definitely a good alternative.how to trace the path
Thx for tutorial! I was looking for resizing info other than
GetThumbnailImage. Though when I compared my resized pics with those generated from 'gthumb', the quality of mine isn't good enough (and they take less space), even with a quality level of 100. Gthumb uses essentially the same jpeg encoders I would think, but doesn't use C#/.NET. Any suggestions to get yet higher quality thumbs ?I would be interested in seeing your results. When I run the above code at quality 100, I get very nice looking thumbnails. Here's an example I just ran. It was originally a 512x512 that I ran through the
resizeImagefunction, then ran the output through thesaveJpegfuntion.As far as I can tell, there is very little (if any) loss of quality. Here were my steps:
If you want to post links to your images (you won't be able to put an image tag in the comment) and the code you're using, we can take a look to try to see where the error might be.
A comparison of the ouput can be found at http://basik.studentenweb.org/pics/
I now use the exact methods (resize and save) presented here and:
I should also mention I am using mono instead of .NET since I'm working on a Linux environment. But i don't think that should matter ?
I installed Mono (on my Windows machine), compiled, and ran the code and I got the exact same thumbnail that I got using .NET. Mono isn't a 100% implementation of .NET (although they're very close) and I'm guessing you ran across a bug in their Linux version. I did some research and couldn't find any instances of other people experiencing the same issue. If you have a Windows machine available, try running the code on that and if the results are better, post a bug report to Mono. If there is a bug, they may have some known work-arounds.
Very helpful tutorial. Good luck.
Thankx.
Finally i found what i'm looking for....
here the image format is of jpg.. can i use it fot gif.. by replacing
i didnt run the code..
Ram, yes you can. That's the only thing you have to change in order to make it a gif file. Remember that it will use a default color pallet of 256 colors so quality might be an issue depending on your application.
Reddest, thanks for ur reply.
Hello, thank you for this tutorial. I tried to try the cropping funtion but it seems like I missed something and it's not working.
Here is the code:
the cropImage in my code is same from the cropImage method here.
Thank you!
Kim, you code looks fine. The problem is I don't know what output you're expecting. Can you be more specific on what exactly isn't working? Is it cropping incorrectly, or not cropping at all? I just ran the crop code on the flower image above and everything seemed to work fine.
Great work, thanks!
Hey, Hows it going, I have a very newby type of question. When I try to run this in Visual studio, I get "Error while trying to run project,unable to start debugging, Binding handle is invalid" thanks
It sounds like there is a problem with your Visual Studio settings. I don't have any experience with that error myself, but here's an MSDN forum that seems to address a similar problem.
Unable to debug: The binding handle is invalid.
Hopefully that helps a little.
That did it, I was able to find the link below from your link. It was due to the Terminal Services being disabled. They say it has been fixed in vs sp1 -more info at the link below if anyone needs it. THANKS AGAIN
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105751
Another newbie question; When I upload the files to a server, and attempt to open the page, the application file is displayed as xml source code in the browser. I am using apache/fed core 3, Do I need to install some sort of xml parsing module? thanks
Thanks for the Post, it really helped. I'm working on a project using WIA, I scanned a documents and need to CROP out 4 different areas.
How can I determine the Rectangle of each area by simply Loading the Scanned Image in a picture box and dragging my mouse over each area like in Microsoft Paint?.
This will really save me from the over head of using WIA to scan and crop for each area.
Thanks a lot...Great tutorial !
this code is upload the image and i want to resize the image after uploading so pla give me code ans
After the image has been uploaded, it's in the hands of your server code. If your server is written in ASP.NET, you can use the same code that's in this post. If your server is written in another language, you'll have to do some searching on how to resize images with your specific language.
Saved me a few hours and from having to use a Graphics object to do cropping. Cheers muchly
Thank you!
Finally! A way to crop and flip my background image!
Great tutorial!
Awesome! I was trying to figure out how to use the Developer's Image Library (DevIL). All I wanted was to be able to open, resize, crop, and save a picture, so It seemed way overkill to use their library. Your tutorial is exactly what I wanted! Thanks!
Excellent snippet of code. Explained everything clearly and saved me a couple of hours of work. Much appreciated
Thanks for this very useful resizeImage method.
Thanks a lot!! I was looking for something like this for my project.
How come the gif loses its animation if cropped?
how can i save a rectangle as xml data.
i want to save this rectangle
Thanks very much for the code. I integrated it into something I was doing for some staff at work who wanted to be able to re-size images simply. I threw a little c# application together and it works pretty well.
One issue i do have it that the GDI+ component seems to fail if the image is non-colour managed. In other words, I can use it for RGB/8 (8 bit RGB images) but other colour spaces (like RGB/8# - unmanaged) causes a GDI+ error.
Does anyone have any experience in that area?
The downside for me is that my application only works with some jpgs - not all jpgs.
Thanks again for the code. Very cool and useful for people new to it all (like I am)
Cliff
Thank you so much! Well done!
So cool!
great article but i want to know how can i use the code to resize certain image to fixed width (100 for example) and keeping the height proportional?
thx2u
Thank you for this great code. I'm having one odd problem though, and if anyone has any ideas I'd be grateful.
My problem is that after calling resizeImage, my original source file is locked. So when the user modifies the image and tries to save it, I can't overwrite the original image (my goal).
Here's my client usage snippet:
When I bypass the resize method and simply do a File.Copy(src,dst), the source file is not locked. I've spent two days trying to work around this--it's killing me.
I think the issue is related to the "redefinition" of "img". It is allocated in the client code (new Bitmap(source)), then more space is allocated in resizeImage as "b" (thumbnail Image), then "b" is returned and assigned to "img". Is there an orphaned IO stream for the first "img" allocation that holds an open handle to the source file?
This problem is a bit over my head, so any help would be awesome! Thanks.
I'm on ASP.NET, Framework 3.5, IIS6, Win 2k3 server
Update regarding my previous comment: My problems don't appear to have anything to do with imageResize(). I'll keep chugging along in search of a solution.
Regarding quality of the created thumbnail, I have to say it's stunning.
John
I had the same problem with the handle to the source image remaining open and what solved for me was forcing the Graphics instance to be released.
Hope this helps.
Javier
Thanks! This is just what I've been looking for.
Oh, the time this could have saved me in the past!
Love the tutorial. One question, though. You supply a cropping routine, which is wonderful, but one thing that would be of great interest to me is a tutorial about selecting the image to be cropped. There seems to be few good examples of selecting a rectangle on the screen a la Windows Paintbrush or Photoshop. Any ideas where I might find such an example?
This is cool!!! Thanks mannnnn, that is what I am talkin about!
Thanks man!
Simple and beautiful....
smple the best
Thanks a lot. Keep up the good work. This resize method was exactly what I needed. God Bless
many thanks
how am i suppose to do multiple upload of files?? can you guys help me?
terific tutorial i ve gained lot of knoweledge by thius
Terrific site. I was in the deep woe.but now i found my requiremetns Lot of Thanks for code
Hi,
I have a TIFF image whose background color is Black and the text i.e the foreground color is in white. I want it to be changed to White background and Black foreground. can you please help me on how to achieve this?
Thanks a lot for that code....
Thanks for the code, I tried a lot of examples but this one does exactly what I wanted.
I save PNG image from RTF file. All possible resizing-cropping-saving with this excellent code leave image in a strange aspect. It is like elements (characters from “symbol font”) are too near between them… Someone can help me?
thanks sir u hve done good job.
Thanks! Hundreds of images resized at the click of a button; it's a beautiful thing. This is awesome.
Good code, just one thing: Avoid calling dispose yourself, use a using-block:
it's not 100% necessary, but it's good pratice, and if you felt you should call dispose, you might as well use using.
There is a useful ActiveX control called AccessImage. It does all the work about images for you.
FOR DEVELOPER: binds to database field (if needed), auto resizes big images, can manage pics in external storage, generates previews.
FOR END USER: load from file, paste from clipboard, scan or drag n drop image in 1 click. Crop it right on the form. Undo if something goes wrong.
Watch action video here: http://access.bukrek.net/tutorial/action-video/
you all are the best, I have been trying to write an implementation of an image resizing and cropping algorithm, using VS2005. Email me any code at bpgueze@hotmail.com
BTW, change this: if (nPercentH \< nPercentW)
to this: if (nPercentH > nPercentW)
if you want to superscribe the image to the cliprect. This code inscribes the image to the cliprect.
thanks
Hi everyone. The issue we’re having is we have a wpf richtextbox, and we’re pasting images into it, but we want to be able to limit the physical data size, not the display size of the images being pasted in. In other words, if a user paste in an image that’s 2MB, we want to automatically shrink it down to a more manageable size. We have to have many users who share richtextbox data. So their text and images gets saved up to a cloud database so other users may download it. Please note that when an image gets pasted in, it’s a System.Windows.Controls.Image object.Any help will be greately appreciated
I'm using the cropping code, and I'm getting an outOfMemoryException error.
I don't even know where start with this.
Are the X and Y values legit? i.e. is the new Rectangle within the frame image dimensions?
There's a small error in resizing code. This can cause an off-by-one error on some some input/output combinations. As in, the returned image is one pixel fewer in width or height than what was requested.
It should read:
int destWidth = (int) Math.Round(sourceWidth * nPercent); int destHeight = (int) Math.Round(sourceHeight * nPercent);
How does Math.Round fix that?
My guess is because casting to int takes the floor, and rounding will get you the nearest whole integer.
The one worry I have about that is that we would round up to the next pixel when not needed. Therefore having the 1 pixel issues but just having 1 too many.
Thanks for another great tutorial!
I tried it just now. And it seems as if part of the code will come in extremely handy in a project I'm working on where size, but not necessarily quality, matters.
Thanks again for providing us with very very very useful code! :)
Thank You, It is Great !
Good one. Good explanation. I always take pictures from my camera at a bigger size but then resize it to upload to web. I was using the image editing softwares to resize the images, now I can write my own 'batch resizer' (and auto uploader) :)
So Many2 Thanx.. this code i looking for.. confuse at first time finally i use this code and work perfect : String file = Server.MapPath("\~/FileUpload/") + FileUpload1.FileName.ToUpper(); Bitmap gambar = new Bitmap(file); System.Drawing.Image i = resizeImage(gambar, new Size(100, 100)); saveJpeg(Server.MapPath("\~/FileUpload/aaa.jpg"), (Bitmap)i, 100);
Thanx!
Great Post! Finally got the required solution! Nice work! Keep it up!
It seems when creating a Bitmap in .net 3.5, you have the option to create from an image and resize in one method:
All you have to do is find your new width and height and return the new image with that method.
Hi, would like to know if the code for the crop application shown above is to write at form1.cs or where? I'm a newbie here tried on the crop code but failed. How should I do it? Please help.
thanks
Thanks a ton! I'm a newbie and this code saved me from looking like a bafoon at my job!
thanks.........fine job
Merci ! The quality is better than when I used GetThumbnailImage.
does anybody know how to automatically save multiple images? above code works if you have one image..what if you have a few? does image.save have a way of saving images without specifying the exact directory path??
great article, this is working perfectly. thanks for sharing.
Thanks very much
Hello Reddest,
I developed an application that allows the user to move/resize/edit/save graphical controls such as TextBoxes, PictureBoxes.
Right now I am facing a problem which is editing (and so on) Pictures/Text Larger than The screen. I have tried to solve it by allowing my Customized Panel (which contains all of the user-added controls) to autoscroll (canvasPanel.autoscroll = true).
However, because the image is larger than the screen, whenever I save the modifications to a file, only the visible part of it gets saved -drawn and saved-!
I searched all over the internet and nobody seems to know how to solve that problem or even to suggest ideas or whatsoever!
I would be very greatful to you if you could just point out ideas or simply suggest related websites or anything, because I have tried many ways to solve this without any success...
Thank you very much, ZD
Hi great article and was very helpful. Can you explain how can I increase dpi of an image thanx :)
Your tutorial is so cool, that i read it twice! Thanks for saving time because i was going to implement bicubic interpolations by hands!
You're cool guy you write such wonderfull things
very nice code thank you
this is a very helpful code
thank you very much!!
Hi,
Great code, thanks.
Quick question: After resizing my image I'm left the black sections to top and bottom of the new image. Is there a way to crop these away?
Graham.
Hi everyone, Could anyone tell me how to get the stream of the new resized file without saving it to some directory??
Also, how to change the brightness or gamma of the image??
hello friends, i have tiff file and in this file has written some data or lines so i just want to copy lines or data and past in notepad or MS word file.. so is it possible or not.. can we copy data in tiff file.. its urgent and reply me ASAP.. please give me code or demo...
hello i tried to open the code in microsoft visual studio 2008 but i couldn't open it. i would like to see how the program looks like
Easy to understand and very helpful! Thanks so much!
Very helpful article. Many thanks.
First off, just wanna say great article. I've implemented a different cropping method using unmanaged code that is much faster than Bitmap.Clone. It's about 2x faster for cropping large areas >1000x1000px and 100x faster for small areas \<200x200px.
Raptor00 : This is the best I ever seen on internet. I have tried for a long time to split my jpg files at 60000x10000 pixels, and your routine worked... THANK YOU!
I am using this code to show an error when file is open:
try { stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); } catch (IOException) { MessageBox.Show("file is open!"); } The problem is that code is not working with pictures (jpg, bmp and other) and with folders.
Is there anything that I am missing?
good job really useful :)
hi, can anybody help me about plate recognition C# algorithm
Thanks for your kindness to share your experience. I had used your method to solve a "resizing" problem, and the program performance wonderfully.
I've just discovered this code - and it works great.
However, I've noticed that there's some sort of memory leak in the code.
I'm building a screensaver, and in testing this I'm loading each image 1 second after the other. During testing I got an out of memory exception and I'm trying to find the cause of that. I've modified the code to
private Image resizeImage(Image imgToResize, Size size) { return imgToResize; }
and the memory leak goes away.
Any ideas??
Peter
Bitmap implements IDisposable. The code in the tutorial should have been calling Dispose on the Bitmap object that's being created in that function.
Very good job. It wood be better if you copy the code in the 13th comment on how to use this methodes for noobies like me. It took me some time to find out how to use this methodes. Anyway now that I understood the code is very useful. Thank you.
Just a note, Bitmaps can be manipulated in streams so if you are having issues writing the file then editing it and trying to overwrite it rather do the resize in a MemoryStream. Works nicely for web apps and reduces the disk IO. The MemoryStream can be created using a byte array for those that didn't know.
Thanks for a well written tutorial. Keep up the effort
Check this Article: http://www.mindstick.com/Articles/b1984687-85b1-469f-b874-c6b0fd4f1d48/?Resizing%20Image%20in%20C
Your effort is very much appreciated.
I used the image crop & was good for purpose
Thanks
I have a little problem... I know how to use C. But I really can't find a good version of C#... Some help please....
i am getting low quality, when i resize small size to big size.
is there any possibilty for implementing complex image editing tools
Hello, i have an embedded circuit am designing (Home security Burglar alarm),it has webcam connected to it then to my Pc serialport,in event of burglar breaking into my home (by tripping the sensors) the device sends letter like " c " to the Pc serialport which signals my C# application to activates for my webcam (30secs to 2minutes) to take capture images of the burglar and save it on my harddrive with different default names at different intervals this happens once my sensors are tripped on my hardware.
hello, Any buddy can tell me about the how can be do the color separation in the c# means find the separate weights of the blue, red , green color in a single image
hi , i want code for display popup box and crop after upload the image to my database.can any body please help me.this is my mail id svmbabu547@gmail.com.
Thanks a lot...Great tutorial !
To fix the light border around some resized images, you need to set the other 5 quality settings to High on the Graphics object and use an ImageAttributes instance with TileModeXY set for the last parameter of DrawImage.
For a list of the other 29 GDI bugs to avoid, see http://nathanaeljones.com/163/20-image-resizing-pitfalls/
For an open-source implementation without these bugs, see the http://imageresizing.net project.
Good post. Thanks
is there any javascript involved in it?? I want a a croping and resizing like facebook where a client can upload and crop its picture.
Many Thanks chillaxdesigns@gmail.com
nyc code and its relly help:)
Thanks
can u suggest how to select an already drawn line and then resize it.. i m currently developing a cad like application in c#.
Extension Methods are great here:
may the good Lord bless you and you entire household...Great Code
Resize worked perfectly. Thanks
when i crop an .jpg image and save it, the program changes the image extention to .png i don't want to change the image extension. is there any solution?
I want it in Web Application Form
public static class ImageExtensions { public static Image ScaleToFit(this Image helper, double Height, double Width) { double percentWidth = (double)Width / (double)helper.Width; double percentHeight = (double)Height / (double)helper.Height;
double multiplier = 0;
if (percentWidth > percentHeight) multiplier = percentHeight; else multiplier = percentWidth; return helper.GetThumbnailImage((int)(helper.Width * multiplier), (int)(helper.Height * multiplier), null, IntPtr.Zero); }
}
Thank you!!! Hails from Mexico!
When converting, how do you preserve the DPI for the saved image?
Superb! Helped me back in VS 2005.. but now I am using VS 2010.. is there anything equivalent you have for this version? thanks again!
thanks a lot :) it is really helpful to me in current project :D thanks again ...
i have a few c# image editing codes , i want to share those with you.