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

Is there a benefit to using Graphics.DrawImage(Image, RectangleF destRect, RectangleF srcRect, GraphicsUnit srcUnit) when the image is a Bitmap?

除非我遗漏了什么位图是量化的(面向像素)。那么当有人尝试以下操作时会发生什么:

   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' 的在线文档对此没有任何说明。

定义 "benefit"。您会改用什么重载? IE。 "benefit" 与什么相比?

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

其次,Graphics 对象可以配置为以多种方式进行亚像素采样,在这种情况下,小数像素值可能有意义,即使所描述的单位是像素.

你问 "what's going on under the hood",但我担心这部分对于 Stack Overflow 来说是一个太宽泛的问题。 Graphics 对象在 Windows 平台上使用时使用 GDI+ 作为底层机制; 具体 发生在 Graphics 对象的不同配置上的答案需要一篇冗长的论文。

如果您想要那个级别的详细信息,正确的起点是原生 Windows API 中 GDI+ 的 MSDN 文档。对于 Graphics 的大部分内容,.NET API 和本机之间存在一对一的对应关系。


顺便说一句,要清楚:您在这种情况下的坐标是 float 值。我会谨慎使用 "decimal" 一词,因为 .NET/C# 有一个实际的 decimal 类型,而您肯定不会使用它。 :)

就是not well known,如果你画个图,比如:

graphics.DrawImage(image, top, left);

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

如果你想绘制一个没有任何缩放的图像,你必须明确地给出DrawImage图像的大小:

graphics.DrawImage(img, top, left, img.Width, img.Height);

通过调用 DrawImage 匹配原始图像像素大小的目标矩形,您可以避免 resampling/rescaling.

红利阅读

  • .NET: What does Graphics.DrawImageUnscaled do?