AvaloniaUI / Avalonia

Develop Desktop, Embedded, Mobile and WebAssembly apps with C# and XAML. The most popular .NET UI client technology
https://avaloniaui.net
MIT License
25.56k stars 2.21k forks source link

Creating a Bitmap from a ZipArchiveEntry stream throws an error #17252

Open ErisLoona opened 1 week ago

ErisLoona commented 1 week ago

Describe the bug

Heyo! When using Avalonia.Media.Imaging.Bitmap, using new Bitmap() on a Stream provided by a System.IO.Compression.ZipArchiveEntry throws the error "Unable to load bitmap from provided data". In my testing on the same file, System.Drawing.Bitmap works with no issues.

To Reproduce

I have the following code:

using ZipArchive archive = ZipFile.OpenRead(path);
foreach (ZipArchiveEntry entry in archive.Entries)
    if (entry.Name == "cover.jpg")
    {
        CoverImage.Source = new Bitmap(entry.Open()); //Error is thrown here
        break;
    }

I have also tried Bitmap b = new Bitmap(entry.Open()); instead with the same result.

Expected behavior

No response

Avalonia version

11.1.4

OS

No response

Additional context

No response

stevemonaco commented 5 days ago

I can reproduce. As a workaround, copying to a MemoryStream beforehand works for me. Probably still a bug though so keep the issue open.

eg.

using var entryStream = entry.Open();
using var memory = new MemoryStream();
entryStream.CopyTo(memory);
memory.Seek(0, SeekOrigin.Begin);

CoverImage.Source = new Bitmap(memory);

For reproducing:

using ZipArchive archive = ZipFile.OpenRead(@"D:\avalonia-logo.zip"); // Fixup path
foreach (ZipArchiveEntry entry in archive.Entries)
{
    if (entry.Name == "avalonia-logo.png")
    {
        using var entryStream = entry.Open();
        using var bitmap = new Bitmap(entryStream);
    }
}

avalonia-logo.zip

The culprit could be an unsupported scenario in SkiaSharp:

https://github.com/AvaloniaUI/Avalonia/blob/a04af7cebf3d49b81c228cbb6c18eb2e860ada58/src/Skia/Avalonia.Skia/ImmutableBitmap.cs#L24-L30

I don't know the SK* APIs well, but Avalonia could write some specialized code for DeflateStream. It lacks certain capabilities such as Position, Length, and seeking.