2012-12-28 93 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;