专栏首页walterlv - 吕毅的博客.NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)

.NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)

.NET 程序如何获取图片的宽高(框架自带多种方法的不同性能)

发布于 2020-02-17 08:32 更新于 2020-02-17 00:47

获取图片宽高的方法有很多种,本文介绍 .NET 中获取图片宽高的几种方法并评估其性能。如果你打算对大量图片进行一些处理,本文可能有用。


本文即将评估的方法

本文即将采用以下四种方法获取图片:

  1. System.Drawing.Imaging.Metafile
  2. System.Drawing.Bitmap
  3. System.Windows.Media.Imaging.BitmapImage
  4. 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 框架中原生自带的获取图片尺寸的方法来说:

  1. System.Windows.Media.Imaging.BitmapDecoder 的整体性能是最好的
  2. 对于同一张图,System.Windows.Media.Imaging.BitmapImage 的运行时间不随次数的增加而增加,其内部有缓存

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • git subtree 的使用

    这样,B 仓库的整体,会被作为 A 仓库中一个 SubFolder/B 的子文件夹,同时保留 B 仓库中的整个日志记录。

    walterlv
  • 制作 Windows 10 安装盘,解决大于 4GB 的 Windows 10 镜像在 UEFI 模式下的安装问题

    2018-02-22 14:14

    walterlv
  • Win2D 中的游戏循环:CanvasAnimatedControl

    发布于 2018-11-11 21:35 更新于 2018-11...

    walterlv
  • 【蒲慕明院士】人工智能可借鉴的 5 大自然神经网络特性(35PPT)

    【新智元导读】2016中国人工智能大会(CCAI 2016)日前在京召开。中国科学院外籍院士、中国科学院神经学研究所所长蒲慕明27日发表演讲《脑科学能为人工智能...

    新智元
  • C# 数据操作系列 - 3. ADO.NET 离线查询

    在上一篇中,我故意留下了查询的示范没讲。虽然说可以通过以下代码获取一个DataReader:

    程序员小高
  • 大数据基础系列之kafkaConsumer010+的多样demo及注意事项

    一,KafkaConsumer使用要点解释 1,基本介绍 该客户端用户透明的处理kafka Broker的失败,透明的适应topic在集群中的迁移。这种客户端也...

    Spark学习技巧
  • 前沿 | Nature:用机器学习预测干细胞外观

    选自Nature 作者:Amy Maxmen 机器之心编译 参与:黄小天、吴攀、微胖 ? 源自皮肤的人类干细胞的 3D 图,其中蓝色表示 DNA、紫色表示细胞膜...

    机器之心
  • 融合基因调控预测可视化网站

    前两天我们介绍了两个和融合基因有关的数据库,其中涉及到融合基因的查找和功能预测。对于融合基因的功能的话,FusionGDB数据库主要是来分析发生融合基因之后,对...

    匹咔球
  • 深度学习: Full Connection (全连接层)

    在 Caffe 中,全连接层 的 type (层类型) 为 Inner Product 。 输出一个简单向量(把输入数据blobs的width和height...

    JNingWei
  • iBatis for net 框架使用

    简介:ibatis 一词来源于“internet”和“abatis”的组合,是一个由Clinton Begin在2001年发起的开放源代码项目,到后面发展的版本...

    Java中文社群_老王

扫码关注云+社区

领取腾讯云代金券