2013-04-03 164 views
2

我正在接收ARGB8888格式的位圖,但我需要通過一些只接受RGB565的算法來處理它。我想使用Renderscript將此位圖轉換爲新格式,但似乎分配和分配輸出應該相等(或兼容)。 bitmapIn是類型ARGB_8888的和bitmapOut是類型的RGB_565Renderscript從ARGB8888轉換到RGB565

所致: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中如何做這種類型的轉換?

回答

3

我找不到與RGB565圖像一起使用的正確Renderscript類型,但uint16_t可以工作(至少在Nexus S上)。正如Tim Murray的回答,你必須分別綁定輸入或輸出分配。

這裏是的renderScript因爲,那裏的輸入RGB8888分配單獨的約束轉化率和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(); 
4

最簡單的方法是將輸出分配傳遞給內核,並將輸入分配綁定爲rs_allocation。使用rsGetElementAt_uchar4訪問分配,執行轉換並返回一個短。

+0

我仍然得到類型轉換錯誤:RSRuntimeException:類型不匹配與U16! RS函數:ushort __attribute __((kernel))root(uint32_t x,uint32_t y){return 65535; } Java:在分配爲RGBA_8888時,輸出爲RGB_565,通過mScript.set_in_allocation(mAllocationIn)綁定; – BCL 2013-04-04 17:33:14