標籤:modify ber set source 方法 comment res wpf 類的方法
原文:【C#/WPF】修改映像的DPI、Resolution
問題:
WPF中預設使用的映像的DPI是96。如果我們使用的圖素的DPI不是96時(比如是72),那麼WPF會把圖片的DPI自動改為96,導致映像載入出來的實際大小Width和Height會比想要的大(原圖顯示大小會是實際圖大小的72/96 = 3/4),比片會在Image控制項內顯示超框了。
如何發現問題的:
這個問題是Debug中從Bitmap身上的HorizontalResolution、VerticalResolution屬性探索的。(Resolution本應該為72,卻變成了96)。Bitmap在轉為BitmapImage 時,會導致原圖的DPI從72變為96!
思路:想辦法將DPI從96修改回設計的72。
WPF的Image控制項顯示圖片時,控制項要求的Source賦實值型別為ImageSource,該類型及其子類都可以用於給Image控制項設定圖片,繼承關係:
BitmapImage --> BitmapSource --> ImageSource
即使用以上三種的任一類型都可以給Image控制項賦值圖源。選擇根據實際需求,因為還要考慮到類型間的轉換。
由於這些類型不通用(BitmapImage 類暫時只看到WPF在用到),現在要改用通用的Bitmap類型。即操作Bitmap類型,最後再轉型為BitmapImage (或BitmapSource / ImageSource)給前台Image控制項使用。(可以寫一個XAML的轉換器,或者Controller層轉型)。
想通過代碼動態修改每張圖片的DPI,發現BitmapImage類身上與DPI相關的屬性基本上都是唯讀。而Bitmap類身上的HorizontalResolution和VerticalResolution屬性是唯讀,但有一個SetResolution()方法。可以使用該方法修改Resolution了。
還有一種比較另類的方法。BitmapImage身上DecodePixelWidth和DecodePixelHeight可讀可寫,而且該屬性也會影響到映像顯示的真實寬高。那麼可以在不改變DPI的情況下,改變這兩個屬性來實現映像的縮放。代碼如下:
public static void ModifyBitmapImageDecodePixel(BitmapImage bi, System.Drawing.Bitmap bitmap){ double scale = 72.0 / 96.0; // 因為Bitmap轉BitmapImage時,DPI從96變成了72,導致映像變大。 bi.DecodePixelWidth = (int)(bitmap.Width * scale); bi.DecodePixelHeight = (int)(bitmap.Height * scale);}
小結:修改DPI或Resolution最終都可以修改映像的真實顯示大小。
本文僅是記錄一下WPF有這麼一個預設映像DPI是96的坑。
【C#/WPF】修改映像的DPI、Resolution