我試圖通過本機功能,使用從安卓在行動(第二版;你也可以看到它here)採取一段代碼轉換爲灰度圖像。不幸的是,返回的位圖對象,而不是灰度,最終是空的。本機位圖處理和ALPHA_8
這是我如何加載文件(.png)圖像:
Bitmap original = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample, options);
有一些安全條件,位圖通(請檢查以下內容)。以下是一個Java本機函數的定義:
public native void convertToGray(Bitmap bitmapIn,Bitmap bitmapOut);
和呼叫:
// Grayscale bitmap (initially empty)
Bitmap gray = Bitmap.createBitmap(original.getWidth(),original.getHeight(),Config.ALPHA_8);
// Native function call
convertToGray(original,gray);
和這裏的功能:
JNIEXPORT void JNICALL Java_com_example_Preprocessor_convertToGray(JNIEnv * env, jobject obj, jobject bitmapcolor,jobject bitmapgray)
{
AndroidBitmapInfo infocolor;
AndroidBitmapInfo infogray;
void* pixelscolor;
void* pixelsgray;
int ret;
int y;
int x;
LOGI("convertToGray");
if ((ret = AndroidBitmap_getInfo(env, bitmapcolor, &infocolor)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infocolor.width,infocolor.height,infocolor.stride,infocolor.format,infocolor.flags);
if (infocolor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
return;
}
LOGI("gray image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infogray.width,infogray.height,infogray.stride,infogray.format,infogray.flags);
if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
LOGE("Bitmap format is not A_8 !");
return;
}
if ((ret = AndroidBitmap_lockPixels(env, bitmapcolor, &pixelscolor)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
// modify pixels with image processing algorithm
for (y=0;y<infocolor.height;y++) {
argb * line = (argb *) pixelscolor;
uint8_t * grayline = (uint8_t *) pixelsgray;
for (x=0;x<infocolor.width;x++) {
grayline[x] = 0.3 * line[x].red + 0.59 * line[x].green + 0.11*line[x].blue;
}
pixelscolor = (char *)pixelscolor + infocolor.stride;
pixelsgray = (char *) pixelsgray + infogray.stride;
}
LOGI("Done! Unlocking pixels...");
AndroidBitmap_unlockPixels(env, bitmapcolor);
AndroidBitmap_unlockPixels(env, bitmapgray);
}
的彩色位被正確地傳遞和加工環節該代碼似乎工作正常,但bitmapgray保持空。我想我錯過了一些關鍵的東西。
測試環境:emulator,v2.2。使用此版本時,當從主線程調用本機代碼時,此功能可用。在2.3仿真器上,無論調用C代碼的線程或加載位圖的方式如何,函數都不起作用。 Android NDK:4b & 6b。
更新#1:你會找到完整的源代碼here。
UPDATE#2: RGB_565代替ALPHA_8給出了一些結果。它似乎甚至沒有Java中的setPixels()適用於ALPHA_8,並且我有 問題查找有關此配置類型的信息。任何形式的幫助將是 非常讚賞。
你有沒有考慮嘗試使用字節緩衝區作爲輸出?如果這有效,那麼我們可以更確定AndroidBitmap有什麼問題......還有'bitmapIn','bitmapOrig'和'original'是同一個對象嗎? –
我對JNI完全陌生,所以不,我沒有嘗試過。我會試一試,然後回報。我仍然會感激一些提示或方向,可以加快這個過程。並且,是的,bitmapIn = bitmapOrig = original(對於後兩者抱歉;我應該更清楚一點;修復它)。 –
@SamuelAudet:好的,我試過[這一個](http://imrannazar.com/Augmented-Reality-with-the-Android-NDK:-Part-2)。結果是*幾乎*空白位圖(具有黑色僞像的白色表面(隨機黑色點))。其他人是否會善意給這個鏡頭? –