This is the example scenario. You have been asked to make a page that enables a user to upload any image they want so that it can be manipulated to ensure it is 200px x 200px and compressed to a smaller file size. I won't talk you though how to make the uploading part as there are a plethora of blogs discussing that already. What I will discuss is how to resize crop and compress that image.
Say you have an image that is 1000px x 800px. There are 3 main steps to converting it to a compressed 200px x 200px image:
Resizing an image
To resize it the key is that it needs to keep the same aspect ratio whilst being a lot smaller.So the expected outcome of this stage will be that the shortest of the two dimensions will be 200px, the other will be larger and the aspect ratio will remain the same. Begin code:
private byte[] GetCroppedImage(byte[] originalBytes, Size size, ImageFormat format) { using (var streamOriginal = new MemoryStream(originalBytes)) using (var imgOriginal = Image.FromStream(streamOriginal)) { //get original width and height of the incoming image var originalWidth = imgOriginal.Width; // 1000 var originalHeight = imgOriginal.Height; // 800 //get the percentage difference in size of the dimension that will change the least var percWidth = ((float)size.Width / (float)originalWidth); // 0.2 var percHeight = ((float)size.Height / (float)originalHeight); // 0.25 var percentage = Math.Max(percHeight, percWidth); // 0.25 //get the ideal width and height for the resize (to the next whole number) var width = (int)Math.Max(originalWidth * percentage, size.Width); // 250 var height = (int)Math.Max(originalHeight * percentage, size.Height); // 200 //actually resize it using (var resizedBmp = new Bitmap(width, height)) { using (var graphics = Graphics.FromImage((Image)resizedBmp)) { graphics.InterpolationMode = InterpolationMode.Default; graphics.DrawImage(imgOriginal, 0, 0, width, height); } } } }
Cropping an image
After the last step you are left with an image that is 250px x 200px. As you will notice that is still an aspect ratio of 5:4 so it does not look squashed. However this still isn't the right size so you will now need to crop it.You are now intending to cut off the excess from both sides to reduce the width whilst leaving the height the same. This will leave you with a 200px x 200px image. Code on:
private byte[] GetCroppedImage(byte[] originalBytes, Size size, ImageFormat format) { using (var streamOriginal = new MemoryStream(originalBytes)) using (var imgOriginal = Image.FromStream(streamOriginal)) { //get original width and height of the incoming image var originalWidth = imgOriginal.Width; // 1000 var originalHeight = imgOriginal.Height; // 800 //get the percentage difference in size of the dimension that will change the least var percWidth = ((float)size.Width / (float)originalWidth); // 0.2 var percHeight = ((float)size.Height / (float)originalHeight); // 0.25 var percentage = Math.Max(percHeight, percWidth); // 0.25 //get the ideal width and height for the resize (to the next whole number) var width = (int)Math.Max(originalWidth * percentage, size.Width); // 250 var height = (int)Math.Max(originalHeight * percentage, size.Height); // 200 //actually resize it using (var resizedBmp = new Bitmap(width, height)) { using (var graphics = Graphics.FromImage((Image)resizedBmp)) { graphics.InterpolationMode = InterpolationMode.Default; graphics.DrawImage(imgOriginal, 0, 0, width, height); } //work out the coordinates of the top left pixel for cropping var x = (width - size.Width) / 2; // 25 var y = (height - size.Height) / 2; // 0 //create the cropping rectangle var rectangle = new Rectangle(x, y, size.Width, size.Height); // 25, 0, 200, 200 //crop using (var croppedBmp = resizedBmp.Clone(rectangle, resizedBmp.PixelFormat)) { } } } }
Compressing the image
You now have the image to the correct size but for the web it is not really optimised.You now want to compress the image down from the current 4 bytes per pixel (32bit) image, which would be ~156KB (for a 200x200 image!). Time to compress:
private byte[] GetCroppedImage(byte[] originalBytes, Size size, ImageFormat format) { using (var streamOriginal = new MemoryStream(originalBytes)) using (var imgOriginal = Image.FromStream(streamOriginal)) { //get original width and height of the incoming image var originalWidth = imgOriginal.Width; // 1000 var originalHeight = imgOriginal.Height; // 800 //get the percentage difference in size of the dimension that will change the least var percWidth = ((float)size.Width / (float)originalWidth); // 0.2 var percHeight = ((float)size.Height / (float)originalHeight); // 0.25 var percentage = Math.Max(percHeight, percWidth); // 0.25 //get the ideal width and height for the resize (to the next whole number) var width = (int)Math.Max(originalWidth * percentage, size.Width); // 250 var height = (int)Math.Max(originalHeight * percentage, size.Height); // 200 //actually resize it using (var resizedBmp = new Bitmap(width, height)) { using (var graphics = Graphics.FromImage((Image)resizedBmp)) { graphics.InterpolationMode = InterpolationMode.Default; graphics.DrawImage(imgOriginal, 0, 0, width, height); } //work out the coordinates of the top left pixel for cropping var x = (width - size.Width) / 2; // 25 var y = (height - size.Height) / 2; // 0 //create the cropping rectangle var rectangle = new Rectangle(x, y, size.Width, size.Height); // 25, 0, 200, 200 //crop using (var croppedBmp = resizedBmp.Clone(rectangle, resizedBmp.PixelFormat)) using (var ms = new MemoryStream()) { //get the codec needed var imgCodec = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == format.Guid); //make a paramater to adjust quality var codecParams = new EncoderParameters(1); //reduce to quality of 80 (from range of 0 (max compression) to 100 (no compression)) codecParams.Param[0] = new EncoderParameter(Encoder.Quality, 80L); //save to the memorystream - convert it to an array and send it back as a byte[] croppedBmp.Save(ms, imgCodec, codecParams); return ms.ToArray(); } } } }
There you go. Your massive image is looking good to the correct size whilst being a much leaner version of former self. Congratulations!
A quick warning to everybody thinking about using System.Drawing (or GDI+) in an ASP.NET environment. It's not supported by Microsoft and MSDN (as of recently) clearly states that you may experience memory leaks.
ReplyDeleteClearly GDI+ is a legacy API and one should opt for image processing using WPF in general.
Here's a quote from http://msdn.microsoft.com/en-us/library/system.drawing.aspx:
Classes within the System.Drawing namespace are not supported for use within a Windows or ASP.NET service. Attempting to use these classes from within one of these application types may produce unexpected problems, such as diminished service performance and run-time exceptions. For a supported alternative, see Windows Imaging Components.
Cool. I've never heard of WIC so it sounds interesting and I'll have a look.
ReplyDeleteJust to make clear the code above isn't thrown together. It evolved with time because as you suggested it is too easy to mistakenly create performance issues when using GDI+. Just see how many times I've written 'using' above!
Anyway, please be assured the above code is highly optimised and tested and has run successfully in a high traffic production environment for a few months now.
Excellent! Thanks for sharing Colin!
ReplyDelete@Anders Borum: Actually, despite what MSDN (incorrectly) states, WIC is NOT supported for use within an ASP.NET service. As WPF wraps WIC, it is subject to the same problems WIC faces. WIC is also only available on Server 2008 and higher, instability will result on OSes where WIC MTA threading isn't available.
ReplyDeleteYou can read it for yourself (Note #2) at the end of this MS blog: http://weblogs.asp.net/bleroy/archive/2009/12/10/resizing-images-from-the-server-using-wpf-wic-instead-of-gdi.aspx
Also, using WPF or WIC will require you place the entire ASP.NET app in Full Trust mode, destroying any sandbox-level security you would have had. GDI works properly even on low-trust scenarios.
--------
To all readers.
Take a look at http://imageresizing.net/
It's free, it's open, and it's reliable. It's fast, well tested, and refined. It even has a NuGet package. And it is thoroughly documented. What are you waiting for?
BUT - If you don't like using existing code, well tested libraries, or simply enjoy the Windows API so much you HAVE to write your own image resizing module, please read the list of pitfalls you need to avoid (these were compiled over many years and many versions of the aforementioned library).
http://nathanaeljones.com/163/20-image-resizing-pitfalls/
Hope this helps!
Nathanael Jones
Nice one.....
ReplyDeletei have been looking for this thx dude
Great Work... Thanks...very very much
ReplyDeleteThanks! It works great!
ReplyDeleteThanks. It works just great!
ReplyDeleteThis is what I need! It works great for me. Thank you!
ReplyDeleteinstagram search
Motifz Designer Lawn. 1, 2 & 3 Piece Unstitched Premium Embroidered Lawn 2019, Premium embroidered Lawn, Premium lawn, Premium lawn 2019, Motifz, Premium lawn in Pakistan Summer collection. Shipping worldwide. Stitching option available.
ReplyDeleteIt is really nice to get the instructions of Image functionalities using the .NET.
ReplyDeleteDo you know? Data breaches on personal computers cause harms to individuals identity, to prevent such attacks use McAfee antivirus and if you want to make sure it is worth it, then take the McAfee Free Trial
I want to protect my important data from virus attacks, so I prefer the McAfee antivirus program to keep protected my important information for various malicious attacks. I have tried my possible efforts to install it, but I failed to do it.
ReplyDeletemcafee.com/activate
www.mcafee.com/activate
mcafee activate
McAfee antivirus allows you to protect your computer from suspicious malwares and keep your files safe. Visit mcafee.com/activate
ReplyDeleteand activate your antivirus.
mcafee.com/activate
www.mcafee.com
www.mcafee.com/activate
Really very happy to say, your post is very interesting to read. You’re doing a great job. Keep it up, and also visit our site to get latest news about Marvel Studios and their actress.
ReplyDeleteIron Man Armour
Avengers Endgame
We are Ring gear pinions, Rueda de corona y piñón gear manufacturers for application in agricultural tractors, Agri machines, automobiles, cars, buses and trucks and we also cater to export markets. We have state of the art manufacturing facility with more than 100 Gleason Machines imported for USA. for any query mail us on : goela.parts@gmail.com
ReplyDeletegearbox
crown wheel pinion
spiral bevel gears
staight bevel gear
transmission gear shafts
differential gears
Goela Engineers is currently one of the leading Axle shafts manufacturers in India. We are manufacturing rear axle shafts, P.T.O. shafts, differential axle, propeller shafts for Commercial Vehicles and axle shafts and supply in India and overseas
ReplyDeleteaxle shafts
rotavator gear shafts
gearbox
bevel gears
face gears
Tractor Spare Parts Catalog online - Ford Tractor, Massey Ferguson Tractor, IMT Tractor, UTB Tractor, MTZ tractor, Eicher tractor, swaraj tractor, mahindra tractor
ReplyDeletetractor spare parts
mtz tractor parts
utb tractor parts
massey ferguson tractor parts
imt tractor parts
ford tractor parts
gearbox
Are you interested more to know about how to Update Garmin GPS easily? For detailed information please visit our website or call us.
ReplyDeleteit was a wonderful chance to visit this kind of site and I am happy to know. thank you so much for giving us a chance to have this opportunity.. videoproduktion
ReplyDelete
ReplyDeleteنقل عفش من الدمام الى الرياض نقل عفش من الدمام الى الرياض
ارخص نقل عفش بمكة ارخص نقل عفش بمكة
نقل عفش من جدة الى الاردن نقل عفش من جدة الى الاردن
نقل عفش
For such purposes a good web connection is required with stable speed in order to buffer the video or the movie efficiently. Moreover, online movie download features are also available via proper subscription to such legit sites.
ReplyDeleteffmovie
Social media is an inexpensive way to get the word out about your movie and create a killer viral buzz online.123movie
ReplyDeleteEquipment from these kind of providers are inexpensive, usually is not commercial grade (but rather equipment meant for personal use) or that is under-powered for an outdoor movie setting. Their equipment is really ment for indoor movie events.
ReplyDelete123 movies
Every single person involved in the making of your film has a story and an angle you can pursue media.0123movies
ReplyDeleteAnd this ties in that a time will come when audiences will grow out of movies which rely on special effects and big star names to entertain and start turning there back on movies which have no originality or fail to deliver a different angle on an old storyline.
ReplyDelete0123movie
Halo, Bingun cari situs Agen judi online Taruhan terpercaya.? YUK GABUNG DI BINTANG BOLA YANG MENYEDIAKAN BERBAGAI JENIS TARUHAN
ReplyDelete-> SBO
-> IBC
-> JOKER
-> TOGEL
Bintang Bola juga memberikan bonus:
-> Cash Back 10%
BINTANG BOLA
WhatsApp: +855-81-287-168
Live Chat 24.JAM
حمل بار
ReplyDeleteGomovies
ReplyDeleteخرید آس سولفام
ReplyDeleteBuy online wholesale printed candle boxes and packaging at easy prices and shipping worldwide, with 24/7 customer support. Get a free custom quote now!!
ReplyDeleteBuy online wholesale printed custom candle boxes and packaging at easy prices and shipping worldwide, with 24/7 customer support. Get a free custom quote now!!
ReplyDelete
ReplyDeletefmovies
xmovies8
0123moviesfree
Blackbird packaging provide you with any size, shape design, custom cbd bath bomb boxes sooner than any other packaging competitor in the market
ReplyDeleteCloud Computing Projects
ReplyDeleteNetworking Projects
Final Year
Projects for CSE
JavaScript Training in Chennai
JavaScript
Training in Chennai
The Angular Training covers a wide range of topics including Components, Angular Directives, Angular Services, Pipes, security fundamentals,
Routing, and Angular programmability. The new Angular TRaining will lay the foundation you need to specialise in Single Page Application developer.
Angular Training
Hey what a brilliant post I have come across and believe me I have been searching out for this similar kind of post for past a week and hardly came across this. Thank you very much and will look for more postings from you Get for more information mahindra mini tractor
ReplyDeleteWe at Al-Fatah have perfected the floor care with the right variety of Vacuum Cleaners available under one roof. Al-Fatah is a One-Stop Shop for all your home appliances buying needs. Buy best variety of Vacuum Cleaners online in Pakistan at Al-Fatah. Shop Vacuum Cleaners of Top & Genuine Brands in Pakistan at Al-Fatah now!
ReplyDeleteBlackbird packaging provide you with any size, shape design, custom bottle neckers wholesale sooner than any other packaging competitor in the market
ReplyDeleteBlackbird packaging provide you with any size, shape design, wholesale cookie boxes sooner than any other packaging competitor in the market
ReplyDeleteBlackbird packaging provide you with any size, shape design, custom bath bomb boxes sooner than any other packaging competitor in the market
ReplyDeleteIn a film democracy no filmmaker is safe from movie viewer salvos or roses being virtually thrown. I've read posts that start by tearing apart a movie until there is nothing left to attack. movie online 2021
ReplyDeleteFigure below shows a two-frame animation after four tween frames were added. The opacity of the man is 100% in the first frame and 0% in the last frame. Adding five tween frames causes the two images to blend into each other smoothly, or morph (metamorphose). gogo anime
ReplyDeleteThis post is very good I am very happy to see this post. Thanks for sharing such a wonderful article. keep up the work... your site is great, and it's helping us a lot.. this post is unique and interesting, thanks for sharing this awesome info
ReplyDeletemahindra tractors price
Hey , Content quality is a good and nice post. Keep sharing.
ReplyDeleteKhetiGaadi is a one-stop solution for Farmers.
"I didn't realize how animal communication really works until just now. Someone can connect with my cat and read her thoughts and tell me how she's feeling and what she wants... ?! That's amazing! I live for the day when I can do that myself!" 9 anime
ReplyDeleteBecause both tasks access and use your intuition. They both require you to feel and open your senses. Furthermore, they both engage your creative imagination in unique ways. gogoanime - watch anime online
ReplyDeleteHighly sensitive empaths often feel overwhelmed by the world around them. You pick up too much information, feel drained, and often shut down your intuitive gifts and abilities entirely. 4anime
ReplyDeleteYour cat tells you I can feel a pressure growing inside my head, I can't see out of one eye, and the pain is becoming more than I can bear. 123movie
ReplyDeleteBy the 1970's, movie posters used photography, occasionally using drawing and painting styles. 4anime
ReplyDeleteBuy sports bra pakistan online online from ndure at easy prices delivered at your doorstep. Get free shipping
ReplyDeleteBuy gym trousers mens online pakistan from Dshred at best prices delivered at your doorstep. Get free shipping
ReplyDeleteSimply wish to claim ones document is usually as astonishing. This clearness with your write-up is usually simply great in addition to when i can think you are a pro within this theme. อ่านมังงะ
ReplyDeleteI'm impatient for one's then blog post, I値l have a shot at to see the stick of it! อ่านการ์ตูน
ReplyDeletethank you for nice information
ReplyDeletevisit our website: https://uhamka.ac.id/
Your blogs are great. Are you also searching for Help with my Math assignment? we are the best solution for you. We are best known for delivering quality essay writing services to students without having to break the bank
ReplyDeleteI love this. It is soo informative. Are you also searching for cheap assignment writing services we are the best solution for you. We are best known for delivering the best services to students without having to break the bank
ReplyDeleteI have read your writings and I have read articles on this topic in several articles from other sources. I got a lot of information from your writing, is there any other suggestions you can convey regarding the theme of your writing? so that I can get more and more complete information.
ReplyDeleteI certainly thank you for writing this article well, hopefully it will become a reference in journals or other scientific writings and can help many people. thanks.
kunjungin : Kampus terbaik di sumatera utara