DrawImage函數在繪製圖片時,如果有展開會導致自動漸層的問題。具體描述如下。
假設我們要做一個進度條,用自己的png格式圖片作為背景和前景進行繪製,此時必然要展開圖片,一是我們在橫向上要通過展開量來表示不同的進度,二是為了力求節省資源檔體積,我們只要求圖片橫向上有幾個像素表示即可(甚至一個像素)。我們用下面的代碼進行繪製。
Graphics gfx(dc.GetSafeHdc());
gfx.SetInterpolationMode(InterpolationModeNearestNeighbor);
Rect rcDes(0, 0, 100, 20);
gfx.DrawImage(m_pImage, rcDes, 0, 0, m_pImage->GetWidth(), m_pImage->GetHeight(), UnitPixel);
我們會發現輸出與我們想象的有所出入,資源圖片並不是被簡單的橫向展開後均與填滿目的地區域,而是自動加上了漸層效果。當圖片實際尺寸小於目的地區域尺寸時,GDI+展開圖片會預設加上漸層效果。(我不得不說GDI+有點強大得過頭了!)但是我們現在不需要這個討厭的效果,怎麼辦呢?
可能你會很快想到一個代替品,就是使用TextureBrush,代碼如下。
Rect rcImage(0, 0, m_pImage->GetWidth(), m_pImage->GetHeight());
TextureBrush brush(m_pImage, WrapModeTileFlipX, rcImage);
gfx.FillRectangle(&brush, rcDes);
TextureBrush(紋理畫刷)將一幅圖片作為刷子的輸出背景,利用畫刷我們能夠正確輸出我們想要繪製的效果。可能會有人提出疑問:難道DrawImage就不能完成我們想要的功能嗎?如果你仔細看上面的代碼,應該會注意到TextureBrush有個構造參數WrapMode,這個參數設定圖片展開時的填充摸式,WrapModeTileFlipX表示在水平方向上進行交差對稱填充,這樣在水平方向上就不會出現漸層展開了。(還有幾種模式大家可以自行研究)
其實DrawImage函數也有這樣一個參數,因此我們只要用下面的代碼進行繪製就可以了:
ImageAttributes ImgAtt;
ImgAtt.SetWrapMode(WrapModeTileFlipXY);
gfx.DrawImage(m_pImage, rcDes, 0, 0, m_pImage->GetWidth(), m_pImage->GetHeight(),
UnitPixel, &ImgAtt);
ok,這下我們終於可以用DrawImage函數繪製自己想要的效果了。GDI+函數為了封裝更加全面強大的繪製功能,提供了很多重載函數,並且參數也非常多樣,我們在使用過程中很容易陷入複雜的參數設定陷阱。要想充分發揮GDI+強大的功能,熟練應用和經驗積累顯得非常重要。