gpt4 book ai didi

android - 使用 NV21 到位图的 Script Intrinsic YuvTo RGB(支持库)时图像损坏

转载 作者:行者123 更新时间:2023-11-29 19:37:58 25 4
gpt4 key购买 nike

我在使用支持库中的 ScriptIntrinsicYuvToRGB 将图像从 NV21 格式转换为位图 (ARGB_8888) 时遇到问题。下面的代码可以说明问题。

假设我有以下 50x50 图像(下面是设备的屏幕截图,实际上不是 50x50):

enter image description here

然后,如果我通过 YuvImage#compressToJpeg + BitmapFactory.decodeByteArray 将所述图像转换为位图:

YuvImage yuvImage = new YuvImage(example, android.graphics.ImageFormat.NV21, width, height, null);
ByteArrayOutputStream os = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0, 0, width, height), 100, os);
byte[] jpegByteArray = os.toByteArray();
return BitmapFactory.decodeByteArray(jpegByteArray, 0, jpegByteArray.length);

我得到了预期的图像。但是如果我通过 ScriptIntrinsicYuvToRGB 如下转换它:

RenderScript rs = RenderScript.create(context);

Type.Builder tb = new Type.Builder(rs, Element.createPixel(rs,
Element.DataType.UNSIGNED_8, Element.DataKind.PIXEL_YUV));
tb.setX(width);
tb.setY(height);
tb.setYuvFormat(android.graphics.ImageFormat.NV21);
Allocation yuvAllocation = Allocation.createTyped(rs, tb.create(), Allocation.USAGE_SCRIPT);
yuvAllocation.copyFrom(example);

Type rgbType = Type.createXY(rs, Element.RGBA_8888(rs), width, height);
Allocation rgbAllocation = Allocation.createTyped(rs, rgbType);

ScriptIntrinsicYuvToRGB yuvToRgbScript = ScriptIntrinsicYuvToRGB.create(rs, Element.RGBA_8888(rs));
yuvToRgbScript.setInput(yuvAllocation);
yuvToRgbScript.forEach(rgbAllocation);

Bitmap convertedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
rgbAllocation.copyTo(convertedBitmap);

我得到以下损坏的图像:

enter image description here

我注意到这种情况发生在正方形尺寸的图像上,而不是 2 的幂(例如 64x64、128x128 等)。如果我没有尝试正方形尺寸,我就不会注意到这个问题,因为某些图片尺寸(例如 2592x1728)可以正常工作。我错过了什么?

更新:将生成原始图像的代码按要求放入:

int width = 50;
int height = 50;
int size = width * height;

byte[] example = new byte[size + size / 2];
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
example[y * width + x] = (byte) ((x*y / (float)size) * 255);
}
}
for (int i = 0; i < size / 2; i++) {
example[size + i] = (byte) (127);
}

最佳答案

以下代码的行为方式有误:

Type.Builder tb = new Type.Builder(rs, Element.createPixel(rs,
Element.DataType.UNSIGNED_8, Element.DataKind.PIXEL_YUV));
tb.setX(width);
tb.setY(height);
tb.setYuvFormat(android.graphics.ImageFormat.NV21);
yuvAllocation = Allocation.createTyped(rs, tb.create(), Allocation.USAGE_SCRIPT);

如果您使用创建分配的“原始”方式替换它,转换将起作用:

int expectedBytes = width * height *
ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;

Type.Builder yuvTypeBuilder = new Type.Builder(rs, Element.U8(rs))
.setX(expectedBytes);
Type yuvType = yuvTypeBuilder.create();
yuvAllocation = Allocation.createTyped(rs, yuvType, Allocation.USAGE_SCRIPT);

看起来,如果您使用 PIXEL_YUV 定义,则在非 16 的倍数维度上存在大小问题。仍在调查中。

关于android - 使用 NV21 到位图的 Script Intrinsic YuvTo RGB(支持库)时图像损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39028367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com