C# 将 System.Drawing.Bitmap 缩放到给定大小,同时保持纵横比

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10442269/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 13:53:33  来源:igfitidea点击:

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

c#graphicsimaging

提问by Michael J. Gray

I want to scale a System.Drawing.Bitmapto 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.

我想将 a 缩放System.Drawing.Bitmap到至少小于某个固定的宽度和高度。这是为网站上的图片库生成缩略图,所以我想保持纵横比相同。

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.

如果我有一个 4272 x 2848 的图像并且我想将其缩放到 1024 x 768 的大小,那么生成的图像应该是 1024 x 683 并填充(带有黑色边框)到 1024 x 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?

如何使用大于所需尺寸且小于所需尺寸的图像以及填充图像在缩放后无法达到我需要的确切尺寸时执行此操作?

采纳答案by yamen

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.

并且不要忘记执行 abmp.Save(filename)来保存生成的文件。

回答by WHol

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

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

If you want control over interpolation modes see this post.

如果您想控制插值模式,请参阅这篇文章

回答by Trent

Just to add to yamen's answer, which is perfect for images but not so much for text.

只是添加到 yamen 的答案中,这对图像来说是完美的,但对文本来说却不是。

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.

如果您尝试使用它来缩放文本,例如 Word 文档(在这种情况下是 Word Interop 中的字节),您将需要进行一些修改,否则您会在旁边看到巨大的条。

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;
}