2012-12-28 59 views
7

如果您考虑以下图像,它是一个相当基本的图标,大小为32x32。图标周围是透明的矩形,尽管我在测试时用纯色填充了四个角。为什么Graphics.DrawImage会裁剪图像的一部分?

Source Image

现在考虑下面的代码,它只是绘制图像,而是以更大的规模:

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

注意,我画完整的图像,我不试图作物它以任何方式放大它。

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

Painted example

注意到这个问题?顶行和左列中的一半像素已经消失。如果我尝试覆盖这个网格,它看起来非常糟糕,因为网格正确对齐,但图像不是。即使只是将大小加倍到64,64也会引入第一行/列的作物。

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

我也尝试过使用不同的插值模式,但据我所知,通过头痛诱导模糊,像素仍然裁剪,所以我不相信这是由于插值模式。

我也尝试过使用不同的图形模式,但除了它似乎没有帮助的事实之外,我仍然需要坚持使用像素。

出于好奇,我在96dpi上重新尝试了一个图像的新副本,并得到了相同的效果,所以我不认为它是源图像的分辨率。

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

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

谢谢;

回答

7

PixelOffsetMode被默认设置为PixelOffsetMode.Half

指定像素由-.5单位偏移量,在水平方向和垂直方向 ,用于高速平滑处理。

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

尝试将其设置到PixelOffsetMode.None

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

    e.Graphics.PixelOffsetMode = PixelOffsetMode.None; 
    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); 
} 
+6

Rotem公司,谢谢您的回答 - 我不知道这个特殊的性质。我测试了它,但它仍然无法工作。但是,我发现如果将其设置为“HighQuality”,那么我的图像渲染正确。听起来像对我来说是一个愚蠢的默认值,但如果你知道,很容易解决 - 再次感谢! –

+0

我有同样的问题。也不知道“PixelOffsetMode”属性。同样,“PixelOffsetMode.None”对我来说不起作用,尽管是明显的设置,但“PixelOffsetMode.HighQuality”确实有效。 –

1

只是覆盖用户确认济的答复,我没有尝试过自己,问题与PixelOffsetMode.HighQuality代替none解决。

C#

e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; 

我的情况下,C++托管:

e->graphics->PixelOffsetMode = System::Drawing::Drawing2D::PixelOffsetMode::HighQuality;