.net 使用SkiaSharp提取图像子集(裁剪)

bvk5enib  于 2022-12-01  发布在  .NET
关注(0)|答案(1)|浏览(200)

我尝试重新使用GitHub中的一个例子,这个例子是关于用SkiaSharp裁剪图像的。具体来说,我有一个4096 x4096的sprite表单,我想从中提取一个子图像(一个特定的sprite,如果你愿意的话)。为了做到这一点,我使用了下面的代码片段(其中spriteContent是PNG图像的字节数组-byte[]):

var gch = GCHandle.Alloc(spriteContent, GCHandleType.Pinned);
try
{
    var addr = gch.AddrOfPinnedObject();
    using var pixmap = new SkiaSharp.SKPixmap(info, addr);
    SkiaSharp.SKRectI rectI = new SkiaSharp.SKRectI(0, 0, 256, 256);

    var subset = pixmap.ExtractSubset(rectI);

    using var data = subset.Encode(SkiaSharp.SKPngEncoderOptions.Default)

    File.WriteAllBytes("test2.png", data.ToArray());
}
finally
{
    gch.Free();
}

然而,这段代码的输出是这样的图像:

看起来像一个奇怪的输出。我怀疑我正在做一些奇怪的与teh SKRectI声明,其中 true 矩形从来没有使用。我理解它正在做的是创建一个矩形从点0在顶部,0在底部,256像素高,256像素宽(即,管理选择)。如果我调整这一点,让我们说:

SkiaSharp.SKRectI rectI = new SkiaSharp.SKRectI(256, 256, 256, 256);

我得到了一个NullReferenceException,子集中没有任何内容,所以我一定是误解了矩形选择器的工作原理。
你觉得我做错了什么吗

wbgh16ku

wbgh16ku1#

你得到的噪声是由你重新解释原始编码png字节为像素数据引起的。你需要先解码图像:

using var skBitmap = SKBitmap.Decode(spriteContent);

using var pixmap =  new SKPixmap(skBitmap.Info, skBitmap.GetPixels());
SkiaSharp.SKRectI rectI = new SkiaSharp.SKRectI(0, 0, 256, 256);

var subset = pixmap.ExtractSubset(rectI);

using var data = subset.Encode(SkiaSharp.SKPngEncoderOptions.Default);

File.WriteAllBytes(@"test2.png", data.ToArray());

相关问题