獲取圖片寬高的方法有很多種,本文介紹 .NET 中獲取圖片寬高的幾種方法並評估其性能。如果你打算對大量圖片進行一些處理,本文可能有用。

本文即將評估的方法

本文即將採用以下四種方法獲取圖片:

System.Drawing.Imaging.Metafile
System.Drawing.Bitmap
System.Windows.Media.Imaging.BitmapImage
System.Windows.Media.Imaging.BitmapDecoder

System.Drawing.Imaging.Metafile

實際上不要被這個名字誤解了, Metafile 並不是“某個圖片的元數據”,與之對應的 MetafileHeader 也不是“某個圖片的元數據頭”。Metafile 是微軟 Windows 系統一種圖片格式,也就是大家熟悉的 wmf 和 emf,分別是 Windows Metafile 和 Enhanced Metafile。

所以指望直接讀取圖片元數據頭來提升性能的的小夥伴們注意啦,這不是你們要找的方法。

不過爲什麼這個也能拿出來說,是因爲此類也可以讀取其他格式的圖片。

var header = Metafile.FromFile(@"D:\blog.walterlv.com\large-background-image.jpg");
var witdh = header.Width;
var height = header.Height;

能拿到。

System.Drawing.Bitmap

這個實際上是封裝的 GDI+ 位圖,所以其性能最好也是 GDI+ 的性能,然而都知道 GDI+ 的靜態圖片性能不錯,但比起現代的其他框架來說確實差得多。

var bitmap = new Bitmap(@"D:\blog.walterlv.com\large-background-image.jpg");
var witdh = bitmap.Width;
var height = bitmap.Height;

System.Windows.Media.Imaging.BitmapImage

這是 WPF 框架中提供的顯示位圖的方法,生成的圖片可以直接被 WPF 框架顯示。

var bitmap = new BitmapImage(new Uri(@"D:\blog.walterlv.com\large-background-image.jpg", UriKind.Absolute));
var witdh = bitmap.Width;
var height = bitmap.Height;

System.Windows.Media.Imaging.BitmapDecoder

這也是 WPF 框架中提供的方法,但相比完全加載圖片到可以顯示的 System.Windows.Media.Imaging.BitmapImage ,此方法的性能會好得多。

var decoder = new JpegBitmapDecoder(new Uri(@"D:\blog.walterlv.com\large-background-image.jpg", UriKind.Absolute), BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnDemand);
var frame = decoder.Frames[0];
var witdh = frame.PixelWidth;
var height = frame.PixelHeight;

性能對比

爲了測試性能,我使用下面這張非常大的圖,同一張圖運行多次:

分別運行以上四個方法各 1 次:

分別運行以上四個方法各 10 次:

分別運行以上四個方法各 100 次(可以發現大量的 GC):

現在,使用不同的圖片運行多次。

分別運行以上四個方法各 10 張圖片:

分別運行以上四個方法各 100 張圖片(可以發現大量的 GC):

做成圖表,對於同一張圖片運行不同次數:

消耗時間(ms) Metafile Bitmap BitmapImage BitmapDecoder
1次 175 107 71 2
10次 1041 1046 63 17
100次 10335 10360 56 122

對於不同圖片運行不同次數:

消耗時間(ms) Metafile Bitmap BitmapImage BitmapDecoder
1次 175 107 71 2
10次 998 980 83 20
100次 10582 10617 255 204
1000次 127023 128627 3456 4015

可以發現,對於 .NET 框架中原生自帶的獲取圖片尺寸的方法來說:

System.Windows.Media.Imaging.BitmapDecoder
System.Windows.Media.Imaging.BitmapImage

參考資料

相關文章