Pergunta

How can I load an Image in WPF using the DotNetZip ZipEntry class.

using (ZipFile file = ZipFile.Read ("Images.zip"))
{
    ZipEntry entry = file["Image.png"];
    uiImage.Source = ??
}
Foi útil?

Solução

ZipEntry type exposes an OpenReader() method that returns a readable stream. This may work for you in this way:

// I don't know how to initialize these things
BitmapImage image = new BitmapImage(...?...);
ZipEntry entry = file["Image.png"];
image.StreamSource = entry.OpenReader(); 

I am not certain this will work because:

  • I don't know the BitmapImage class or how to manage it, or how to create one from a stream. I may have the code wrong there.

  • the ZipEntry.OpenReader() method internally sets and uses a file pointer that is managed by the ZipFile instance, and the readable stream is valid only for the lifetime of the ZipFile instance itself.
    The stream returned by ZipEntry.OpenReader() must be read before any subsequent calls to ZipEntry.OpenReader() for other entries, and before the ZipFile goes out of scope. If you need to extract and read multiple images from a zip file, in no particular order, or you need to read after you're finished with the ZipFile, then you'll need to work around that limitation. To do that, you could call OpenReader() and read all the bytes for each particular entry into a distinct MemoryStream.

Something like this:

  using (ZipFile file = ZipFile.Read ("Images.zip"))        
  {        
      ZipEntry entry = file["Image.png"];
      uiImage.StreamSource = MemoryStreamForZipEntry(entry);        
  } 

 ....

private Stream MemoryStreamForZipEntry(ZipEntry entry) 
{
     var s = entry.OpenReader();
     var ms = new MemoryStream(entry.UncompressedSize);
     int n; 
     var buffer = new byte[1024];
     while ((n= s.Read(buffer,0,buffer.Length)) > 0) 
         ms.Write(buffer,0,n);
     ms.Seek(0, SeekOrigin.Begin);
     return ms;
}

Outras dicas

You could potentially use a BitmapSource, but the raw image data will still need to be decompressed, I'm not sure if opening the zip in the manner that you do actually decompresses on the fly so that, or not; but once you have that you ought to be able to do something like the following:

BitmapSource bitmap = BitmapSource.Create(
    width, height, 96, 96, pf, null, rawImage, rawStride);

Where rawImage would be the bytes of the images file in the form of an array. Other arguments include the DPI and pixel format, which you should now or be able to determine.

In order to get the rawStride value, MSDN has the following sample as an example:

PixelFormat pf = PixelFormats.Bgr32;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top