如何在 SkiaSharp 中将字节数组转换为 SKBitmap?

Par*_*thi 5 2d asp.net-core-mvc .net-core skiasharp .net-standard

SKBitmap.Bytes 是只读的,关于如何 Marshal.Copy 字节数组到 SKBitmap 有什么建议吗?我正在使用下面的代码片段,但它不起作用。

代码片段:

    SKBitmap bitmap = new SKBitmap((int)Width, (int)Height);
    bitmap.LockPixels();
    byte[] array = new byte[bitmap.RowBytes * bitmap.Height];
    for (int i = 0; i < pixelArray.Length; i++)
    {
        SKColor color = new SKColor((uint)pixelArray[i]);
        int num = i % (int)Width;
        int num2 = i / (int)Width;
        array[bitmap.RowBytes * num2 + 4 * num] = color.Blue;
        array[bitmap.RowBytes * num2 + 4 * num + 1] = color.Green;
        array[bitmap.RowBytes * num2 + 4 * num + 2] = color.Red;
        array[bitmap.RowBytes * num2 + 4 * num + 3] = color.Alpha;
    }
    Marshal.Copy(array, 0, bitmap.Handle, array.Length);
    bitmap.UnlockPixels();
Run Code Online (Sandbox Code Playgroud)

Mat*_*hew 10

您始终需要进行一些封送处理,因为位图位于非托管/本机内存中,而字节数组位于托管代码中。但是,您也许可以执行以下操作:

// the pixel array of uint 32-bit colors
var pixelArray = new uint[] {
    0xFFFF0000, 0xFF00FF00,
    0xFF0000FF, 0xFFFFFF00
};

// create an empty bitmap
bitmap = new SKBitmap();

// pin the managed array so that the GC doesn't move it
var gcHandle = GCHandle.Alloc(pixelArray, GCHandleType.Pinned);

// install the pixels with the color type of the pixel data
var info = new SKImageInfo(2, 2, SKImageInfo.PlatformColorType, SKAlphaType.Unpremul);
bitmap.InstallPixels(info, gcHandle.AddrOfPinnedObject(), info.RowBytes, null, delegate { gcHandle.Free(); }, null);
Run Code Online (Sandbox Code Playgroud)

这会固定托管内存并将指针传递给位图。这样,两者都访问相同的内存数据,并且不需要实际进行任何转换(或复制)。(使用后必须取消固定内存的固定,以便 GC 可以释放该内存。)

另外在这里: https: //github.com/mono/SkiaSharp/issues/416