编程语言
首页 > 编程语言> > c# – DrawImage缩放原始图像

c# – DrawImage缩放原始图像

作者:互联网

我正在垂直和水平拼接几个图像,使用C#中的Bitmap和System.Drawing.Graphics创建一个更大的图像(其中总宽度和高度是各个图像的宽度和高度的总和).各个图像的大小为256像素×256像素.

当我使用System.Drawing.Graphics中的DrawImage时,为什么我会得到原始图像的缩放和/或放大版本?

这是原始图像:

original image

当我以编程方式检索图像并在代码中写入文件时,我得到以下内容:

var result = httpClient.GetStreamAsync(/* url */);
var bitmap = new Bitmap(await result);
...
using (var memory = new MemoryStream())
{ 
   using (var fs = new FileStream(/* path */, FileMode.OpenOrCreate, FileAccess.ReadWrite))
   {
        bitmap.Save(memory, ImageFormat.Png); // I save to .png if that makes a difference
        var bytes = memory.ToArray();
        await fs.WriteAsync(bytes, 0, bytes.Length);
   }
}

programmatic retrieval of image in code

我没看见有分别.到现在为止还挺好.

但是,当我尝试水平缝合图像时,我得到以下结果:

注意:作为参考,上面的图像位于下面拼接图像的最右侧.

horizontally stitched image

它看起来缩放,放大,并且绝对不像上面原始或以编程方式检索的单个图像.

这是我用来将图像拼接在一起的代码:

注意:如果byWidth为true,我会水平缝合图像.

private Bitmap MergeImages(IEnumerable<Bitmap> images, bool byWidth)
{
    var enumerable = images as IList<Bitmap> ?? images.ToList();

    var width = 0;
    var height = 0;

    foreach (var image in enumerable)
    {
        if (byWidth)
        {
            width += image.Width;
            height = image.Height;
        }
        else
        {
            width = image.Width;
            height += image.Height;
        }
    }

    var bitmap = new Bitmap(width, height);
    using (var g = Graphics.FromImage(bitmap))
    {
        var localWidth = 0;
        var localHeight = 0;

        foreach (var image in enumerable)
        {
            if (byWidth)
            {
                g.DrawImage(image, localWidth, 0);
                localWidth += image.Width;
            }
            else
            {
                g.DrawImage(image, 0, localHeight);
                localHeight += image.Height;
            }
        }
    }

    return bitmap;
}

解决方法:

是的,DrawImage根据正在绘制的图像的DPI设置缩放图像输出.以72 DPI保存的位图图像将被缩放以匹配您正在绘制它的屏幕的96 DPI(或者您的屏幕实际设置为的任何DPI).这里的想法是应该使源分辨率(DPI)与目标分辨率(DPI)相匹配,以保持分辨率独立性.

令人困惑的是,即使是DrawImageUnscaled方法也使用这种基于DPI的缩放逻辑.实际上,这是因为DrawImageUnscaled方法只是DrawImage的一个重载的简单包装器.从概念上讲,这对我来说似乎是个错误.

无论哪种方式,解决方案都很简单:明确地将所需的图像大小传递给DrawImage调用.基本上,您正在强制它扩展到所需的大小:

g.DrawImage(img, 0, 0, img.Width, img.Height);

这是KB317174年的准记录.

标签:c,image-manipulation,system-drawing
来源: https://codeday.me/bug/20190527/1165095.html