为什么Graphics.DrawImage裁剪我的图像的一部分?

Ric*_*oss 9 c# graphics gdi+ drawimage

如果你考虑下面的图像,它是一个相当基本的图标,大小为32x32.图标周围是一个透明的矩形,虽然我在测试时用纯色填充了四个角.

来源图片

现在考虑一下这个代码,它只是绘制图像,但规模更大:

protected override void OnPaint(PaintEventArgs e)
{
  base.OnPaint(e);

  e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
  e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel);
}
Run Code Online (Sandbox Code Playgroud)

请注意,我正在绘制完整的图像,我不会尝试以任何方式裁剪它,只需将其放大即可.

最后,这是测试给我的输出:

画的例子

注意问题?顶行和左列中的一半像素消失了.如果我然后尝试在此顶部覆盖一个网格,它看起来非常糟糕,因为网格正确对齐,但图像不是.即使只是将大小加倍到64,64引入了第一行/列裁剪.

注意,我也尝试偏移目标矩形,以防它在0,0之前绘制,但事实并非如此.

我也试过使用不同的插值模式,但据我所知,引起模糊的头痛,像素仍然被裁剪,所以我不相信这是由于插值模式.

我也试图使用不同的图形模式,但除了它似乎没有帮助的事实,我还是需要坚持使用像素.

出于好奇,我再次尝试使用96dpi的新图像副本并获得相同的效果,因此我认为这不是源图像的分辨率.

抓住吸管而Rectangle不是使用RectangleF也没有效果.

任何人都可以提供任何线索,说明为什么这种明显的作物正在发生?

谢谢;

Rot*_*tem 8

PixelOffsetMode默认情况下设置为PixelOffsetMode.Half:

指定像素在水平和垂直方向上偏移-.5个单位,以进行高速抗锯齿处理.

在您的情况下,原始图像中的半个像素在结果图像中是8个像素,这正是您所缺少的.

尝试将其设置为:PixelOffsetMode.None PixelOffsetMode.HighQuality

protected override void OnPaint(PaintEventArgs e)
{
     base.OnPaint(e);

     e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
     e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
     e.Graphics.DrawImage(Properties.Resources.icon_32a, new RectangleF(0, 0, 512, 512), new RectangleF(0, 0, 32, 32), GraphicsUnit.Pixel);
}
Run Code Online (Sandbox Code Playgroud)

  • Rotem,谢谢你的回答 - 我不知道这个特殊的财产.我测试了它,但它仍然无法正常工作.但是,我发现如果我将它设置为"HighQuality",那么我的图像就会正确呈现.对我来说听起来像是一个愚蠢的默认值,但如果你知道的话很容易解决 - 再次感谢! (6认同)