Decoded Bitmap from BLOB is null when previously stored in db using SKBitmap.Bytes.

-Nexus--Nexus- GBMember

Hi guys!

I'm new here but a pretty experienced C# dev.

I'm using refactoring my System.Drawing code in a .Net Core serverside console app. These are my two conversion methods that help the app store and retrieve bitmaps to and from my SQLite db. (please excuse extra lines of code that are there for testing)

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

        //var bm = SKBitmap.Decode(temp);

        return temp;
    }

    public SKBitmap Byte2Image(byte[] byteArrayIn)
    {
        //return SKBitmap.Decode(byteArrayIn);

        MemoryStream ms = new MemoryStream(byteArrayIn);
        ms.Seek(0, SeekOrigin.Begin);
        using (var inputStream = new SKManagedStream(ms))
        {
            inputStream.Seek(0);
            var temp = SKBitmap.Decode(inputStream);

            return temp;
        }
    }

When I use them on images I previously stored in the SQLite db with System.Drawing Bitmaps, the Byte2Image works fine, if with lower quality than I want (secondary issue).

When I store new images using Image2Byte results, the Byte2Image always returns null when it tries to Decode what comes back from the db.

In fact, the commented line in Image2Byte (var bm = SKBitmap.Decode(temp);), when uncommented, always produces a 'bm' of null.

Can anyone see what's going wrong here?

The images are downloaded by another (async) method in the first place.
There is definitely varied data consistent with the image in the byte array.

Cheers

Best Answer

Answers

  • mattleibowmattleibow ZAXamarin Team Xamurai

    You might be using the wrong mechanism for storing the bitmap:

    • SKBitmap.Bytes returns the memory as a byte array (not encoded/raw memory)
    • SKBitmap.Decode is trying to decode the bytes, but they aren't encoded.

    The best way to resolve this is to encode the bitmap and then store it:

    public byte[] Image2Byte(SKBitmap bitmap)
    {
        using (SKPixmap pixmap = bitmap.PeekPixels())
        using (SKData data = pixmap.Encode(SKEncodedImageFormat.Png, 100)) {
            byte[] bytes = data.ToArray();
            return bytes;
        }
    }
    

    You probably want to encode the bitmap as this will contain the image properties (width, height, color type, alpha type). If you want raw bytes, you can save the SKBitmap.Bytes, but you will have to store the data from SKImageInfo in the database as well as the bytes just contain raw pixel data.

  • -Nexus--Nexus- GBMember

    Thanks, Matthew. You were right, of course!

    Is the reason some images (the ones previously stored in the db using System.Drawing Bitmaps converted to Byte[] in the BLOB) would fail to be Resized? The resultant SKBitmap is null.

    Thanks

  • -Nexus--Nexus- GBMember

    Hi!

    Thanks for your reply, I appreciate the guidance.

    Here is my updated resize method:

        private SKBitmap ResizedBitmap(SKBitmap bitmap, int size)
        {
            SKImageInfo moddedII = bitmap.Info;
            if (size != 0)
            {
                moddedII.Height = size;
                moddedII.Width = size;
            }
    
            return bitmap.Resize(moddedII, SKBitmapResizeMethod.Triangle);
        }
    

    I updated it on reading your recent answer, however I get the exception:

    {System.Exception: Unable to allocate pixels for the bitmap.
    at SkiaSharp.SKBitmap..ctor(SKImageInfo info, Int32 rowBytes)
    at SkiaSharp.SKBitmap.Resize(SKImageInfo info, SKBitmapResizeMethod method)
    at McDuff.Modules.Visual.NewBitmapMethods.ResizedBitmap(SKBitmap bitmap, Int32 size) in C:\Users\Chew\Documents\Visual Studio 2017\Projects\Discord 1.0 Projects\McDuff2\McDuff2\McDuff2\Modules\Visual\NewBitmapMethods.cs:line 351
    at McDuff.Modules.Visual.NewBitmapMethods.DrawCircleClippedBitmap(SKCanvas canvas, SKBitmap bitmap, Single left, Single top, Int32 size) in C:\Users\Chew\Documents\Visual Studio 2017\Projects\Discord 1.0 Projects\McDuff2\McDuff2\McDuff2\Modules\Visual\NewBitmapMethods.cs:line 326}

    The images are all square and about 100 pixels in size.

    The bitmap Info for one of them is:

    Thanks, in advance for any insight you might be able to offer!

    Cheers

    M

Sign In or Register to comment.