【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的坑。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM