.NET 程序如何獲取圖片的寬高(框架自帶多種方法的不同性能)
獲取圖片寬高的方法有很多種,本文介紹 .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
參考資料