【问题标题】:When overlaying two identically-sized images, one is offset重叠两张相同大小的图片时,一张是偏移的
【发布时间】:2016-04-25 01:42:02
【问题描述】:

我正在尝试通过将一个图像叠加在另一个图像之上来创建图像。代码有效,但我覆盖的图像似乎有点拉伸,我不知道为什么。

所以代码只是创建了一个空白的红色 24x24 矩形,然后我覆盖了一个 24x24 png 文件,如下所示:

我期待的是这样的:

但我实际上明白了:

Using backGround As New Bitmap(24, 24, Imaging.PixelFormat.Format32bppArgb)
        Using g = Graphics.FromImage(backGround)
            Using brush1 As New SolidBrush(Color.Red)
                g.FillRectangle(brush1, 0, 0, 24, 24)
                Using topimage = Image.FromFile("C:\Scratch\ManNoRecords24.png")
                    g.DrawImage(topimage, New Point(0, 0))
                End Using
            End Using
        End Using
        backGround.Save("C:\Scratch\Emp.png", Imaging.ImageFormat.Png)
    End Using

调试器显示 topImage 的属性:

【问题讨论】:

  • 在调试器中检查topimage的尺寸。这些是什么? 24x24 是否如您所愿?
  • 是的,我检查了它确实是 24x24
  • 是否可能是 png 文件中的 DPI 异常?不同的顶部图片会发生同样的事情吗?
  • @eric - 是的,你在现场,背景是96

标签: .net vb.net image bitmap gdi+


【解决方案1】:

你可以使用

g.DrawImageUnscaledAndClipped(topimage, New Rectangle(0, 0, 24, 24))

相反,以避免在绘制源图像时对其进行任何缩放。这可行,但我实际上不太确定您的解决方案有什么问题。

Reference Source来看,DrawImageUnscaledAndClipped似乎使用Pixel作为图像大小的默认单位,因此忽略了源图像的DPI设置:

/// <include file='doc\Graphics.uex' path='docs/doc[@for="Graphics.DrawImageUnscaledAndClipped"]/*' />
/// <devdoc>
/// </devdoc>
public void DrawImageUnscaledAndClipped(Image image, Rectangle rect) {
    if(image == null) {
        throw new ArgumentNullException("image");
    }

    int width = Math.Min(rect.Width, image.Width);
    int height = Math.Min(rect.Height, image.Height);

    //We could put centering logic here too for the case when the image is smaller than the rect
    DrawImage(image, rect, 0, 0, width, height, GraphicsUnit.Pixel);
}

DrawImageDrawImageUnscaled 不这样做,然后可能会根据其内部 DPI 设置重新缩放图像,Matt 发现该设置小于默认的 96,这会导致图像拉伸:

/// <include file='doc\Graphics.uex' path='docs/doc[@for="Graphics.DrawImageUnscaled"]/*' />
/// <devdoc>
/// </devdoc>
public void DrawImageUnscaled(Image image, Point point) {
    DrawImage(image, point.X, point.Y);
}

【讨论】:

  • 背景的水平和垂直分辨率似乎为96,而磁盘上的PNG由于某种原因具有71.9582,所以这可以解释这种差异
  • @MattWilko 好的,这很难找到。我正在查看绘制图像的参考源。当使用DrawImageUnscaledAndClipped 时,.NET 源代码中的调用专门将GraphicsUnit 设置为Pixel,而其他方法则没有。所以这里忽略了 DPI 设置,而其他方法可能使用 Point 并因此考虑图像 DPI。
  • 感谢您的解释 - 我想我会将图像更改为相同的 DPI 以方便使用。
猜你喜欢
  • 1970-01-01
  • 2012-11-09
  • 1970-01-01
  • 1970-01-01
  • 2021-02-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多