Frage

How can I load an image source directly from a zipfile.

I use DotNetZip.

Below 2 code samples.

Code sample 1 fails to load and display the imagefile.

Code sample 1 I load a zipEntry to a MemoryStream, and creates a BitmapImage to be used as Imagesource but it fails.??? Just for testing I try to save the image from the memorystream, to make sure that the Zip Entry is loaded. It is saved correctly:

        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

Code sample 2 I load a file to a MemoryStream, and creates a BitmapImage to be used as Imagesource with succes.

        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

What is wrong with the MemoryStream in Sample 1 I get a debug message, when I execute sample 1: "A first chance exception of type 'System.NotSupportedException' occurred in mscorlib.dll"

War es hilfreich?

Lösung

The stream seems to be closed by the Extract method. You may however create a second MemoryStream from the buffer of the first one:

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;

Update: Because you know the uncompressed size of the image buffer in advance, you might slightly improve performance by manually providing the buffer that the two MemoryStreams operate on:

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

Andere Tipps

This works too:

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; 
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top