Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将System.Drawing.Bitmap缩放到给定大小,同时保持纵横比_C#_Graphics_Imaging - Fatal编程技术网

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

C# 将System.Drawing.Bitmap缩放到给定大小,同时保持纵横比,c#,graphics,imaging,C#,Graphics,Imaging,我想将系统.Drawing.Bitmap缩放到至少小于某个固定宽度和高度。这是为网站上的图像库生成缩略图,所以我希望保持纵横比不变 我有很多解决方案,但似乎没有一个能真正满足我的需要;它们围绕着基于保持宽度或高度相同但不改变两者的缩放旋转 例如: 如果我有一个4272×2848的图像,并且我想将其缩放到1024×768的大小,那么生成的图像应该是1024×683,并且填充(带有黑色边框)到1024×768 如果图像大于所需大小,小于所需大小,并且在缩放后显示的图像与我所需的精确大小不符,如何处理

我想将
系统.Drawing.Bitmap
缩放到至少小于某个固定宽度和高度。这是为网站上的图像库生成缩略图,所以我希望保持纵横比不变

我有很多解决方案,但似乎没有一个能真正满足我的需要;它们围绕着基于保持宽度或高度相同但不改变两者的缩放旋转

例如:

如果我有一个4272×2848的图像,并且我想将其缩放到1024×768的大小,那么生成的图像应该是1024×683,并且填充(带有黑色边框)到1024×768

如果图像大于所需大小,小于所需大小,并且在缩放后显示的图像与我所需的精确大小不符,如何处理这些图像?

目标参数:

float width = 1024;
float height = 768;
var brush = new SolidBrush(Color.Black);
您的原始文件:

var image = new Bitmap(file);
目标尺寸(比例系数):

调整大小的步骤包括先刷画布:

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

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

位图构造函数内置了调整大小的功能

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");


如果您想控制插值模式,请参阅。

以补充yamen的答案,该答案非常适合图像,但不适合文本

如果您试图使用它来缩放文本,例如Word文档(在本例中是Word Interop中的字节数),则需要进行一些修改,否则会在旁边出现巨大的条形图

也许并不完美,但对我来说很有用

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

为什么你不能用数学来计算其他维度?@CodyGray“其他”维度到底是什么?这是一个二维图像,需要在保持纵横比的同时缩小其比例。我试着只计算纵横比,并计算出接近目标尺寸的宽度和高度的公分母,但从来没有成功过。这会创建一个纯黑色图像。将
var scale
更改为
float scale
。我猜在您的代码中,您的
宽度
高度
可能被声明为
int
,这会导致问题。如果你严格按照我的建议去做,效果会很好。
scale
的全部要点是保持纵横比。完成后删除-1。我知道这是旧的,但这对我有帮助,所以谢谢。但是,我在using块中包装了graph,因为它实现了IDisposable。我看到这也很旧,但尽管我提到Graphics is Disposable(),所以不要忘记将该Graphics对象放入using语句中使用
FillRectangle
方法而不是
Clear
方法有什么特别的原因吗?这将节省创建笔刷和处理它的时间。谢谢。这帮了大忙。我知道这是一个有点老套的答案,但我的新形象看起来模糊有什么原因吗?我需要设置任何插值模式吗?这不只是在一个新的较小位图中绘制原始位图吗?图像的一部分应该被剪切掉。这不就是在一个新的较小的位图中绘制原始位图吗?TFM的链接就在这里:从指定的现有图像初始化位图类的新实例,并缩放到指定的大小。
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;
}