mono/SkiaSharp

SKBitmap.Decode returns null when provided WebClient Stream with certain jpg

Closed this issue · 4 comments

Environment:
Windows 10, .NET Core 2.0 Preview 2, SkiaSharp@1.58.1

SKBitmap.Decode returns null when provided Stream from WebClient for some jpg files.

using (var client = new WebClient())
{
    using (var stream = client.OpenRead(url))
    {
        var bitmap = SKBitmap.Decode(stream); //returns null
    }
}

Interesting enough, the same image will be decoded fine if first downloaded to memory stream. Also works if converted to bytes.

I tried to compare failing/working files, using JPEGSnoop. Found out that the following data is present in the failing files. Not sure if it is exactly the reason, but at least some clue.
image

Please see the repro here:
https://github.com/funkyOne/SkiaSharpStreamIssueRepro

This does seem like a bug. I'm happy to help more, but don't have much expertise in imaging stuff. I can provide more of such images if needed.

Thanks

kodeo commented

I'm having the same issue using HttpClient, e.g.

using (var client = new HttpClient())
{
	var url = "https://image.ibb.co/bO1RLF/broken2.jpg";
	var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
	// var worksWithThis = await response.Content.ReadAsByteArrayAsync();
	using (var stream = await response.Content.ReadAsStreamAsync())
	{
		var skbmp = SKBitmap.Decode(stream);
	}
}

It does seem to be something to do with buffering, because it works if I change to HttpCompletionOption.ResponseContentRead or uncomment the worksWithThis line, but I'm at a complete loss to explain why it affects some files but not others.

Thanks for reporting this.

Hi there

the "bm" in this method

    public byte[] Image2Byte(SKBitmap bitmap)
    {
        var temp = bitmap.Bytes;

        var bm = SKBitmap.Decode(temp);

        return temp;
    }

is always null.

Is it me, or is should this not be happening?

Cheers

@CmdrNexus this is a bug that was fixed dbd09b0

The basic issue is that the .NET and SkiaSharp streams work differently, and I was not properly handling this.