Wpf:从 zip 加载图像源而不保存文件

Posted

技术标签:

【中文标题】Wpf:从 zip 加载图像源而不保存文件【英文标题】:Wpf: Load image source from zip without saving the file 【发布时间】:2014-02-05 15:55:40 【问题描述】:

如何直接从 zipfile 加载图像源。

我使用 DotNetZip。

以下 2 个代码示例。

代码示例 1 无法加载和显示图像文件。

代码示例 1 我将 zipEntry 加载到 MemoryStream,并创建了一个 BitmapImage 用作 Imagesource,但它失败了。??? 只是为了测试,我尝试从内存流中保存图像,以确保加载 Zip 条目。保存正确:

        MemoryStream memoryStream1 = new MemoryStream();

        ZipFile zip = ZipFile.Read(@"D:\myZipArcive.zip");

        ZipEntry myEntry = zip["myfile.jpg"];
        myEntry.Extract(memoryStream1);
        memoryStream1.Close();

        System.IO.File.WriteAllBytes(@"D:\saved.jpg", memoryStream1.ToArray()); 
        //save file just for testing

        BitmapImage src = new BitmapImage();
        src.BeginInit();
        src.CacheOption = BitmapCacheOption.OnLoad;
        src.StreamSource = memoryStream1;
        src.EndInit();

        myImage.Source = src as ImageSource; //no image is displayed

代码示例 2 我将文件加载到 MemoryStream,并成功创建了用作 Imagesource 的 BitmapImage。

        FileStream fileStream = File.OpenRead(@"D:\myFile.jpg");

        MemoryStream memoryStream2 = new MemoryStream();
        memoryStream2.SetLength(fileStream.Length);
        fileStream.Read(memoryStream2.GetBuffer(), 0, (int)fileStream.Length);

        BitmapImage src = new BitmapImage();
        src.BeginInit();
        src.CacheOption = BitmapCacheOption.OnLoad;
        src.StreamSource = memoryStream2;       
        src.EndInit();

        myImage.Source = src as ImageSource; //The image is displayed

示例 1 中的 MemoryStream 有什么问题 当我执行示例 1 时,我收到一条调试消息: "在 mscorlib.dll 中发生了 'System.NotSupportedException' 类型的第一次机会异常"

【问题讨论】:

【参考方案1】:

流似乎已被 Extract 方法关闭。但是,您可以从第一个的缓冲区创建第二个 MemoryStream:

var zipFile = ZipFile.Read(@"D:\myZipArcive.zip");
var zipEntry = zipFile["myfile.jpg"];
var zipStream = new MemoryStream();
zipEntry.Extract(zipStream);

var bitmap = new BitmapImage();

using (var sourceStream = new MemoryStream(zipStream.ToArray()))

    bitmap.BeginInit();
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.StreamSource = sourceStream;
    bitmap.EndInit();


myImage.Source = bitmap;

更新:因为您提前知道图像缓冲区的未压缩大小,您可以通过手动提供两个 MemoryStream 操作的缓冲区来稍微提高性能:

var buffer = new byte[zipEntry.UncompressedSize];
var zipStream = new MemoryStream(buffer); // here
zipEntry.Extract(zipStream);
...
using (var sourceStream = new MemoryStream(buffer)) // and here
...

【讨论】:

@ErikT 请查看我的更新。也许这表现得更好一点。【参考方案2】:

这也有效:

var zipFile = ZipFile.Read(@"D:\myZipArcive.zip");
var zipEntry = zipFile["myfile.jpg"];
var bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = zipEntry.OpenReader();
bitmap.EndInit();
myImage.Source = bitmap; 

【讨论】:

经过一些测试,我注意到使用 Clement 的代码加载图像的速度要快得多。

以上是关于Wpf:从 zip 加载图像源而不保存文件的主要内容,如果未能解决你的问题,请参考以下文章

QML:设置 AnimatedImage 源而不在资源中加载文件

从数据流而不是从文件加载图像

ASP.NET - 如何在浏览器中显示图像而不将图像保存在临时文件中?

如何使用标头php下载zip文件而不将其保存在服务器上

将 WPF 画布保存到文件而不损失质量(不使用位图作为中介)

创建文本文件并添加到zip文件并下载spring boot而不保存在本地服务器中