gpt4 book ai didi

android - 从 ARGB8888 到 RGB565 的 Renderscript 转换

转载 作者:太空狗 更新时间:2023-10-29 16:05:42 24 4
gpt4 key购买 nike

我正在接收 ARGB8888 格式的位图,但我需要通过某种只接受 RGB565 的算法对其进行处理。我想使用 Renderscript 将此位图转换为新格式,但似乎输入分配和输出分配应该相等(或兼容)。bitmapIn是ARGB_8888类型,bitmapOut是RGB_565类型

Caused by: android.renderscript.RSIllegalArgumentException: Allocation kind is PIXEL_RGBA, type UNSIGNED_8 of 4 bytes, passed bitmap was RGB_565

java :

public void convert(final Bitmap bitmapIn, Bitmap bitmapOut)
{
mInAllocation = Allocation.createFromBitmap(mRS, bitmapIn, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
Type.Builder tb = new Type.Builder(mRS, Element.RGB_565(mRS)).setX(bitmapIn.getWidth()).setY(bitmapOut.getWidth());
mOutAllocation = Allocation.createTyped(mRS, tb.create());
// Call custom method (not forEach_root) so we can have uchar4 in and uchar3 out
mScript.forEach_convert(mInAllocation, mOutAllocation);
mOutAllocation.copyTo(bitmapOut);
}

渲染脚本:

// Convert to RGB565 by quantizing the individual channels
void convert(const uchar4* v_in, uchar3* v_out)
{
v_out->x = v_in->x >> 3;
v_out->y = v_in->y >> 2;
v_out->z = v_in->z >> 3;
}

请注意,如果我制作了两个位图 ARGB_8888 并且让 convert() 在两个 uchar4* 上工作(并且只复制 alpha (w) channel ,那么我会看到位图被改变了。

我知道 565 等于 16 位,所以实际上它更可能是 uchar2,但它也与类型分配不兼容。

如何在 Renderscript 中进行这种类型转换?

最佳答案

我找不到用于 RGB565 图像的正确 Renderscript 类型,但 uint16_t 有效(至少在 Nexus S 上)。正如 Tim Murray 的回答,您必须分别绑定(bind)输入或输出分配。

这是执行转换的 Renderscript,其中输入 RGB8888 分配单独绑定(bind),rsForEach 在 RGB565 分配上调用:

#pragma version(1)
#pragma rs java_package_name(uk.co.massycat.renderscriptfun.rsfun)

rs_allocation gInImage;

void root(const uint16_t *v_in, uint16_t *v_out, const void *usrData, uint32_t x, uint32_t y) {
uint16_t colour = 0;

const uchar4 *in_pixel = rsGetElementAt(gInImage, x, y);

uint32_t red = in_pixel->r;
uint32_t green = in_pixel->g;
uint32_t blue = in_pixel->b;

red >>= 3;
green >>= 2;
blue >>= 3;

// red (5 bits)
colour |= red << 11;
// green (6 bits)
colour |= green << 5;
// blue (5 bits)
colour |= blue << 0;
#if 0
// red (5 bits)
colour |= 0x0 << 11;
// green (6 bits)
colour |= 0x0 << 5;
// blue (5 bits)
colour |= 0x1f << 0;
#endif

*v_out = colour;
}

void doWork( rs_script script, rs_allocation alloc_out) {
rsForEach(script, alloc_out, alloc_out);
}

在 RGB565 分配上调用 rsForEach 时,在 Java 端,您必须调用 invoke_doWork 脚本对象方法而不是 forEach_root 脚本对象方法,因为 forEach_root 调用将对 RGB565 分配进行类型检查并抛出异常说明它与 U16 不兼容。

Java 方面:

mInImageAllocation = Allocation.createFromBitmap(mRS, mInBitmap,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
Type.Builder tb = new Type.Builder(mRS, Element.RGB_565(mRS)).setX(mInBitmap.getWidth()).setY(mInBitmap.getHeight());
mOutAllocation = Allocation.createTyped(mRS, tb.create());

mScript.set_gInImage(mInImageAllocation);

mScript.invoke_doWork(mScript, mOutAllocation);
Bitmap tmp_bitmap = Bitmap.createBitmap(mInBitmap.getWidth(), mInBitmap.getHeight(), Bitmap.Config.RGB_565);
mOutAllocation.copyTo(tmp_bitmap);

mAnImageView.setImageBitmap(tmp_bitmap);
mAnImageView.invalidate();

关于android - 从 ARGB8888 到 RGB565 的 Renderscript 转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15795751/

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