从DotNetZip条目加载图像

本文关键字:加载 图像 DotNetZip | 更新日期: 2023-09-27 18:06:12

如何使用DotNetZip ZipEntry类在WPF中加载图像

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

从DotNetZip条目加载图像

ZipEntry type公开了一个返回可读流的OpenReader()方法。这个可以以这种方式为您工作:

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

我不确定这是否会起作用,因为:

  • 我不知道BitmapImage类或如何管理它,或者如何从流创建一个。我可能把代码写错了

  • ZipEntry.OpenReader()方法内部设置并使用一个由ZipFile实例管理的文件指针,可读流仅在ZipFile实例本身的生命周期内有效。由ZipEntry.OpenReader()返回的流必须在任何后续调用ZipEntry.OpenReader()获取其他条目之前读取,并且在ZipFile超出作用域之前读取。如果您需要从一个zip文件中提取和读取多个图像,而没有特定的顺序,或者您需要在完成ZipFile后读取,那么您需要解决这个限制。为此,您可以调用OpenReader()并将每个特定条目的所有字节读取到一个不同的MemoryStream中。

像这样:

  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;
}

您可能会使用BitmapSource,但原始图像数据仍然需要解压缩,我不确定是否以您实际在飞行中解压缩的方式打开zip,或者不;但是一旦你有了这些,你应该能够做如下的事情:

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

其中rawImage是数组形式的图像文件的字节数。其他参数包括DPI和像素格式,您现在应该或能够确定。

为了得到rawStride的值,MSDN有以下示例作为示例:

PixelFormat pf = PixelFormats.Bgr32;
int rawStride = (width * pf.BitsPerPixel + 7) / 8;