简体   繁体   English

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

[英]Extracting image subset (cropping) with SkiaSharp

I am trying to re-purpose an example from GitHub that deals with cropping an image with SkiaSharp.我正在尝试重新使用 GitHub 中的一个示例,该示例涉及使用 SkiaSharp 裁剪图像。 Specifically, I have a 4096x4096 sprite sheet from which I'd like to extract a sub-image (a specific sprite, if you will).具体来说,我有一个 4096x4096 精灵表,我想从中提取一个子图像(一个特定的精灵,如果你愿意的话)。 To do that, I use the following snippet (where spriteContent is a byte array of the PNG image - byte[] ):为此,我使用以下代码片段(其中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();
}

The output of this code is, however, this kind of image:然而,这段代码的output是这样的图像:

格式错误的 PNG 图像

Seems like an odd output. I suspect that I am doing something funky with teh SKRectI declaration, where the true rectangle is never used.似乎是一个奇怪的 output。我怀疑我正在用SKRectI声明做一些时髦的事情,其中从未使用过真正的矩形。 What I understand it to be doing is create a rectangle from point 0 on top, 0 on bottom, 256 pixels tall, 256 pixels wide (ie, manage the selection).我理解它要做的是从顶部的点 0、底部的 0、256 像素高、256 像素宽创建一个矩形(即管理选择)。 If I adjust this to, let's say:如果我将其调整为,让我们说:

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

I get a NullReferenceException and there is nothing in the subset, so I must be misinterpreting how the rectangle selector works.我得到一个NullReferenceException并且子集中没有任何内容,所以我一定是误解了矩形选择器的工作方式。

Any thoughts on what I might be doing wrong here?关于我在这里可能做错了什么的任何想法?

The noise you get is caused by the fact, that you reinterpret raw encoded png bytes as pixel data.您得到的噪音是由于您将原始编码的 png 字节重新解释为像素数据这一事实引起的。 You need to decode the image first:您需要先解码图像:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM