4

I have the following code and I can't see anything wrong, any ideas on what the problem could be?

private static string SaveBaseImage( ZipArchive arc, DBImage image, int imageIndex )
{
    using (var mem = new MemoryStream(image.Data))
    {
        var bmp = BitmapFrame.Create(mem);
        //var bmp = BitmapFrame.Create(m‌​em, BitmapCreateOptions.‌​None, BitmapCacheOption.On‌​Load);
        var codex = bmp.Decoder.CodecInfo;

        var filename = $"{imageIndex}{codex.FileExtensions}";
        var imagezip = arc.CreateEntry(filename,CompressionLevel.Optimal));
        using (var imagestream = imagezip.Open())
        {
            SaveImage( bmp, imagestream);
        }
        return filename;
    }
}

private static void SaveImage(BitmapFrame data, Stream saveStream)
{
    var codex = data.Decoder.CodecInfo;
    var encoder = BitmapEncoder.Create(codex.ContainerFormat);
    encoder.Frames.Add(data);
    encoder.Save(saveStream);
}

when I run it throws

System.NotSupportedException occurred HResult=-2146233067

Message=Specified method is not supported. Source=PresentationCore

StackTrace: at System.Windows.Media.Imaging.BitmapEncoder.Save(Stream stream) at FileFormatters.Export.SaveImage(BitmapFrame data, Stream saveStream)

InnerException: null

The MSDN page says

NotSupportedException :The Frames value that is passed to the encoder is null.

NotSupportedException :The Frames count is less than or equal to zero.

However frames count is 1 and data is not null

further info

arc declared as using (ZipArchive arc = new ZipArchive(stream, ZipArchiveMode.Create))
image.Data is byte[]
codex.FriendlyName = "PNG Decoder"
encoder.CodecInfo.FriendlyName = "PNG Encoder"
MikeT
  • 5,398
  • 3
  • 27
  • 43
  • Try to immediately load the bitmap from the MemoryStream by `var bmp = BitmapFrame.Create(mem, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);` Besides that, couldn't you just write the original `image.Data` to the archive? – Clemens Aug 16 '16 at 10:34
  • @Clemens thanks for your help, unfortunately that was the first thing i thought of had no effect at all, as for skipping the decode i'm afraid not, as the next operation is to draw a strokes collection on top of the frame and save that as a 2nd image – MikeT Aug 16 '16 at 10:39

1 Answers1

4

It seems to be necessary to write the image buffer to an intermediate MemoryStream, before it can be written to a ZipEntry Stream:

private static void SaveImage(BitmapFrame data, Stream saveStream)
{
    var encoder = BitmapEncoder.Create(data.Decoder.CodecInfo.ContainerFormat);
    encoder.Frames.Add(data);

    using (var memoryStream = new MemoryStream())
    {
        encoder.Save(memoryStream);
        memoryStream.Position = 0;
        memoryStream.CopyTo(saveStream);
    }
}
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • 2
    So bitmap encoders don't support compressed streams? that would be useful information to include in the MSDN page – MikeT Aug 16 '16 at 11:04