How do I save an in memory Bitmap to a ZipArchive without saving the Bitmap to the file system first?

1k views Asked by At

So I have some code that takes a capture of the screen and saves it to a jpeg file. This works fine, however I want to instead save the jpeg encoded capture to a new ZipArchive without writing the Bitmap to the file system first.

Here is what I have so far:

FileInfo zipArchive = new FileInfo(fileToZip.FullName + ".zip");

using (ZipArchive zipFile = ZipFile.Open(zipArchive.FullName, ZipArchiveMode.Create)))
{
    ZipArchiveEntry zae = zipFile.CreateEntry(fileToZip.FullName, CompressionLevel.Optimal);
    using (Stream zipStream = zae.Open())
        bmp.Save(zipStream, ImageFormat.Jpeg);
 }

The problem is that on the bmp.Save() line a System.NotSupportedException is thrown

This stream from ZipArchiveEntry does not support seeking.

I've seen a lot of examples that write directly to the Stream returned from zae.Open() so I am not sure why this doesn't work because I figured that all bmp.Save() would need to do is write, not seek. I don't know if this would work but I don't want to have to save the Bitmap to a MemoryStream and the copy that stream to the Stream returned from zae.Open() because it feels like unnecessary extra work. Am I missing something obvious?

1

There are 1 answers

2
Sami Kuhmonen On BEST ANSWER

Many file formats have pointers to other parts of the file, or length values, which may not be known beforehand. The simplest way is to just write zeros first, then the data and then seek to change the value. If this way is used, there is no way to get by this, so you will need to first write the data into a MemoryStream and then write the resulting data into the ZipStream, as you mentioned.

This doesn't really add that much code and is a simple fix for the problem.