DrawImage缩放原始图像 [英] DrawImage scales original image

查看:766
本文介绍了DrawImage缩放原始图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我将水平和垂直方向上的几幅图像缝合在一起,以使用C#中的BitmapSystem.Drawing.Graphics来创建一个更大的图像(其中总宽度和高度是单个图像的宽度和高度的总和).单个图像的大小为256像素x 256像素.

I am stitching several images together vertically and horizontally to create one bigger image (in which the total width and height are the sum of the widths and heights of the individual images) using Bitmap and System.Drawing.Graphics in C#. The size of the individual images are 256 px by 256 px.

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

When I use DrawImage from System.Drawing.Graphics, why do I get a scaled and/or zoomed in version of the original image?

这是原始图片:

当我以编程方式检索图像并用代码写入文件时,得到以下信息:

When I retrieve the image programmatically and write to file in code, I get the following:

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

我没什么区别.到目前为止,一切都很好.

I see no difference. So far, so good.

但是,当我尝试水平缝合图像时,会得到以下信息:

However, when I attempt to stitch images horizontally, I get the following:

注:供参考,以上图像位于下面的拼接图像的最右端.

Note: For reference, the image above is at the far-right in the stitched image below.

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

It looks scaled, zoomed in, and definitely not like the original or programmatically retrieved individual image above.

这是我用来将图像缝合在一起的代码:

Here is the code I use to stitch the images together:

注意:如果byWidthtrue,则我水平拼接图像.

Note: If byWidth is true, I stitch images horizontally.

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)相匹配,以保持分辨率的独立性.

Yes, DrawImage scales the image output based on the DPI setting of the image being drawn. A bitmap image saved at 72 DPI will be scaled to match the 96 DPI of the screen you're drawing it to (or whatever DPI your screen is actually set to). The idea here is that the source resolution (DPI) should be made to match the destination resolution (DPI), in order to maintain resolution-independence.

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

Confusingly, even the DrawImageUnscaled method uses this DPI-based scaling logic. Practically, this is because the DrawImageUnscaled method is just a simple wrapper around one of the overloads of DrawImage. Conceptually, this seems like a bug to me.

无论哪种方式,解决方案都很简单:将所需的图像大小显式传递给DrawImage调用.本质上,您是在强迫它缩放到所需的大小:

Either way, the solution is simple: explicitly pass the desired size of the image to the DrawImage call. Essentially, you are forcing it to scale to the desired size:

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

这是 KB317174 中的准文档.

这篇关于DrawImage缩放原始图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆