我正在接收ARGB8888格式的Bitmaps,但我需要通过一些只接受RGB565的算法来处理它。我想使用Renderscript将此位图转换为新格式,但似乎分配输入和分配输出应该相等(或兼容)。 bitmapIn的类型为ARGB_8888,bitmapOut的类型为RGB_565
引起:android.renderscript.RSIllegalArgumentException:分配类型为PIXEL_RGBA,类型为4字节的UNSIGNED_8,传递的位图为RGB_565
爪哇:
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);
}
的renderScript:
// 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)通道,那么我会看到位图被更改。
我知道565等于16位,所以实际上它更可能是uchar2,但它也与类型中的分配不兼容。
如何在Renderscript中进行此类型转换?
答案 0 :(得分:4)
最简单的方法是将输出分配仅传递给内核,而是将输入分配绑定为rs_allocation。使用rsGetElementAt_uchar4访问分配,进行转换,并返回一个简短的。
答案 1 :(得分:3)
我无法找到与RGB565图像一起使用的正确Renderscript类型,但uint16_t有效(至少在Nexus S上)。正如Tim Murray的回答一样,你必须分别绑定输入或输出Allocation。
这是进行转换的Renderscript,其中输入RGB8888分配单独绑定,并且在RGB565分配上调用rsForEach:
#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();