Scaling a System.Drawing.Bitmap to a given size wh

2019-01-08 18:10发布

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?

3条回答
何必那么认真
2楼-- · 2019-01-08 18:35

Just to add to yamen's answer which is prefect for images but not so much for text. If you are trying to use this to scale text.. like say a word document(which is in this case in bytes from word interop) you will need to make a few modifications or you will get giant bars on the side. May not be perfect but works for me!

using (MemoryStream ms = new MemoryStream(wordBytes))
                {
                    float width = 3840;
                    float height = 2160;

                    var brush = new SolidBrush(Color.White);
                    var rawImage = Image.FromStream(ms);
                    float scale = Math.Min(width / rawImage.Width, height / rawImage.Height);
                    var scaleWidth = (int)(rawImage.Width * scale);
                    var scaleHeight = (int)(rawImage.Height * scale);
                    var scaledBitmap = new Bitmap(scaleWidth, scaleHeight);
                    Graphics graph = Graphics.FromImage(scaledBitmap);
                    graph.InterpolationMode = InterpolationMode.High;
                    graph.CompositingQuality = CompositingQuality.HighQuality;
                    graph.SmoothingMode = SmoothingMode.AntiAlias;
                    graph.FillRectangle(brush, new RectangleF(0, 0, width, height));
                    graph.DrawImage(rawImage, new Rectangle(0, 0 , scaleWidth, scaleHeight));
                    scaledBitmap.Save(fileName, ImageFormat.Png);
                    return scaledBitmap;
                }
查看更多
叼着烟拽天下
3楼-- · 2019-01-08 18:49

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.

查看更多
放荡不羁爱自由
4楼-- · 2019-01-08 19:00

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.

查看更多
登录 后发表回答