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

Wpf:从zip加载图像源而不保存文件,wpf,image,load,zip,memorystream,Wpf,Image,Load,Zip,Memorystream,如何直接从zipfile加载图像源 我使用DotNetZip 下面是2个代码示例 代码示例1无法加载和显示图像文件 代码示例1 我将zipEntry加载到MemoryStream,并创建一个BitmapImage用作Imagesource,但失败了。??? 为了进行测试,我尝试从memorystream保存图像,以确保Zip条目已加载。它已正确保存: MemoryStream memoryStream1 = new MemoryStream(); ZipFile

如何直接从zipfile加载图像源

我使用DotNetZip

下面是2个代码示例

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

代码示例1 我将zipEntry加载到MemoryStream,并创建一个BitmapImage用作Imagesource,但失败了。??? 为了进行测试,我尝试从memorystream保存图像,以确保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中,并创建一个BitmapImage作为Imagesource使用,成功

        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'类型的第一次意外异常”

提取方法似乎已关闭流。但是,您可以从第一个MemoryStream的缓冲区创建第二个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
...
这也有效:

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的代码,图像加载速度要快得多。@ErikT请查看我的更新。也许这会更好一点。