当图像是位图时,使用Graphics.DrawImage(Image,RectangleF destRect,RectangleF srcRect,GraphicsUnit srcUnit)有什么好处?

时间:2016-04-13 14:20:27

标签: c# graphics drawimage

除非我遗漏了某些位图被量化(面向像素)。那么当有人尝试以下内容时会发生什么:

   public void Foo(Bitmap image)
   {
        var destinationRect = new Rectangle(0, 0, 50, 50);
        var resultingSubimage = new Bitmap(destinationRect.Width, destinationRect.Height, PixelFormat.Format24bppRgb);
        using (var graphics = Graphics.FromImage(resultingSubimage))
        {
            graphics.DrawImage(image, destinationRect, new RectangleF(30.3245F /*x*/, 23.234234F /*y*/, 50F, 50F), GraphicsUnit.Pixel);
            // vs graphics.DrawImage(image, destinationRect, new Rectangle(30 /*x*/, 23 /*y*/, 50, 50), GraphicsUnit.Pixel);
        }
   }

注意x和y字段是指向子像素点的小数。但是,甚至存在位图的子像素点这样的事情吗?引擎盖下发生了什么?很抱歉,如果已在其他地方得到解答,但Graphics.DrawImage()和基础p / invoke函数'GdipDrawImageRectRect'的在线文档都没有说明这一点。

2 个答案:

答案 0 :(得分:3)

not well known,如果您绘制图像,例如:

Elector

图像将被缩放。这是因为DrawImage查看图像的dpi设置(例如来自photoshop的72dpi),并缩放图像以匹配目标显示(通常为96dpi)。

如果您想要绘制没有任何缩放的图像,您必须明确给出graphics.DrawImage(image, top, left); 图像的大小:

DrawImage

通过调用graphics.DrawImage(img, top, left, img.Width, img.Height); 与原始图片的像素大小匹配的目标矩形,您可以避免重新取样/重新缩放。

奖金阅读

答案 1 :(得分:2)

定义"福利"。你会用什么超负荷?即"效益"与什么相比?

在处理Bitmap对象时,最重要的是过载是完全无用的。首先,GraphicsUnit值确定如何解释传递给方法的坐标,当然可以传递除GraphicsUnit.Pixel之外的其他内容。例如,假设您使用GraphicsUnit.Inch并且图像的分辨率为120 dpi。然后每个像素只有1/120英寸,对于每像素精度,您的浮点值将是其倍数(即0.0083333333333333的倍数),而不是整数值。

其次,Graphics对象可以配置为以各种方式进行子像素采样,在这种情况下,即使所描述的单位是像素,分数像素值也可能具有意义。 / p>

你问"幕后发生了什么"但是我担心这个部分对Stack Overflow来说太宽泛了。 Graphics对象在Windows平台上使用时使用GDI +作为底层机制;对Graphics对象的不同配置发生的具体的回答将需要冗长的论文。

如果您需要这种详细程度,那么正确的起点将是本机Windows API中GDI +的MSDN文档。对于Graphics的大多数部分,.NET API与本地API之间存在一对一的对应关系。


顺便说一句,要明确:此场景中的坐标是 float 值。我会谨慎使用"十进制"这里,因为.NET / C#有一个实际的decimal类型,你绝对不会使用它。 :)