【问题标题】:How to convert a byte array to SKBitmap in SkiaSharp?如何在 SkiaSharp 中将字节数组转换为 SKBitmap?
【发布时间】:2017-12-29 04:13:40
【问题描述】:

SKBitmap.Bytes 是只读的,关于如何 Marshal.Copy 字节数组到 SKBitmap 的任何建议?我正在使用下面的代码 sn-p 但它不起作用。

代码sn-p:

    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();

【问题讨论】:

    标签: .net-core asp.net-core-mvc 2d .net-standard skiasharp


    【解决方案1】:

    由于位图位于非托管/本机内存中,而字节数组位于托管代码中,您将始终需要进行一些封送处理。但是,您也许可以这样做:

    // 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);
    

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

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

    【讨论】:

    • 它非常有用。谢了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 2014-08-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多