使用WPF图像类 - 获取图像尺寸而不必读取整个文件

21

链接此帖。我想读取图像文件的高度和宽度,而不必将整个文件读入内存。

在该帖中,Frank Krueger提到可以使用一些WPF Imaging类来实现此操作。如何实现?

2个回答

47
这应该可以做到:
var bitmapFrame = BitmapFrame.Create(new Uri(@"C:\Documents and Settings\All Users\Documents\My Pictures\Sample Pictures\Winter.jpg"), BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
var width = bitmapFrame.PixelWidth;
var height = bitmapFrame.PixelHeight;

2
请注意,此方法将对图像文件进行“锁定”。要避免这种情况,请在一个 using 块中创建一个 FileStream(使用 FileMode.Read、FileAccess.Read),然后使用流而不是嵌入式 URI 创建 BitmapFrame。Kent 在这里使用了这种技术:http://stackoverflow.com/questions/767250/using-bitmapframe-for-metadata-without-locking-the-file - Charlie
@Charlie为什么不把代码作为另一种答案写下来,赚取一些声望值呢? - user3083619

23

根据Sir Juice的建议,这里有一些避免锁定图像文件的替代代码:

using (var stream = new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read))
{
    var bitmapFrame = BitmapFrame.Create(stream, BitmapCreateOptions.DelayCreation, BitmapCacheOption.None);
    var width = bitmapFrame.PixelWidth;
    var height = bitmapFrame.PixelHeight;
}

我通过将这段代码包装在 GC.GetTotalMemory(false) 中进行了一次粗略的内存分配检查。我检查了一个4k位图图像(4096x2160,磁盘上约34MB),分配的内存量大约为16kB。 - cod3monk3y
2
此外,使用 SysInternals ProcessMonitor,我观察到仅有 4 个 ReadFile 事件在 (offset,length) = (0,16), (0,14), (14,4), (18,36) 处,总共读取了 70 字节的文件。太棒了! - cod3monk3y
@cod3monk3y 引用 ProcMon - JJS
@Charlie:有没有办法在不加载完整图片到内存的情况下获取图像文件大小? - Koder101

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接