Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scaling a System.Drawing.Bitmap to a given size while maintaining aspect ratio

I want to scale a System.Drawing.Bitmap to at least less than some fixed width and height. This is to generate thumbnails for an image gallery on a website, so I want to keep the aspect ratio the same.

I have some across quite a few solutions but none seem to really do what I need; they revolve around scaling based on keeping the width or the height the same but not changing both.

An example:

If I have a 4272 by 2848 image and I want to scale it to a size of 1024 by 768, then the resulting image should be 1024 by 683 and padded (with a black border) to 1024 by 768.

How can I do this with images larger than the required size and smaller than the require sized and also pad images which don't come out to the exact size I need once scaled?

like image 940
Michael J. Gray Avatar asked May 04 '12 03:05

Michael J. Gray


People also ask

Can bitmap be scaled?

The larger dimension of the target bitmap size is going to match either maxWidth or maxHeight , the second dimension will be scaled proportionally. A new bitmap is created using createScaledBitmap with the correct targetWidth and targetHeight .


2 Answers

The bitmap constructor has resizing built in.

Bitmap original = (Bitmap)Image.FromFile("DSC_0002.jpg"); Bitmap resized = new Bitmap(original,new Size(original.Width/4,original.Height/4)); resized.Save("DSC_0002_thumb.jpg"); 

http://msdn.microsoft.com/en-us/library/0wh0045z.aspx

If you want control over interpolation modes see this post.

like image 121
WHol Avatar answered Sep 19 '22 15:09

WHol


Target parameters:

float width = 1024; float height = 768; var brush = new SolidBrush(Color.Black); 

Your original file:

var image = new Bitmap(file); 

Target sizing (scale factor):

float scale = Math.Min(width / image.Width, height / image.Height); 

The resize including brushing canvas first:

var bmp = new Bitmap((int)width, (int)height); var graph = Graphics.FromImage(bmp);  // uncomment for higher quality output //graph.InterpolationMode = InterpolationMode.High; //graph.CompositingQuality = CompositingQuality.HighQuality; //graph.SmoothingMode = SmoothingMode.AntiAlias;  var scaleWidth = (int)(image.Width * scale); var scaleHeight = (int)(image.Height * scale);  graph.FillRectangle(brush, new RectangleF(0, 0, width, height)); graph.DrawImage(image, ((int)width - scaleWidth)/2, ((int)height - scaleHeight)/2, scaleWidth, scaleHeight); 

And don't forget to do a bmp.Save(filename) to save the resulting file.

like image 22
yamen Avatar answered Sep 19 '22 15:09

yamen