6
私は、アクションでのコード(第2版; hereも参照)から取られたコードを使用して、イメージをネイティブ関数でグレースケールに変換しようとしています。残念ながら、返されたビットマップオブジェクトはグレースケールではなく、空になります。ビットマップが通過することを安全条件の数は(以下を確認してください)がありネイティブビットマップ処理とALPHA_8
Bitmap original = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample, options);
:
これは私が(.PNG)画像をロードする方法です。ここでは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);
}
カラービットマップが正しく渡される、との処理部コードは正常に動作しているようですが、ビットマップグレーは空です。私はここで重要な何かを逃していると思う。
テスト環境:エミュレータ、v2.2。このバージョンでは、ネイティブコードがメインスレッドから呼び出されたときに機能します。 2.3エミュレータでは、Cコードを呼び出すスレッド、またはビットマップのロード方法に関係なく、関数はで動作しません。 Android NDK:4b & 6b。
UPDATE#1:あなたは完全なソースコードhereを見つけることができます。
UPDATE#2: ALPHA_8の代わりにRGB_565が結果を示します。 JavaのsetPixels()もALPHA_8で動作しないようで、この設定タイプの情報を見つけるには の問題があります。どんな種類の助けでも に感謝します。
は、あなたが出力としてのByteBufferを使用しようと考えたことがありますか?それがうまくいくなら、AndroidBitmapに何か問題があることをもっと確かめることができます。また、 'bitmapIn'、' bitmapOrig'、 'original'は同じオブジェクトですか? –
私はJNIについて全く新しいので、試していません。私はそれを打ち明け、そして報告する。私はプロセスをスピードアップできるいくつかのヒントや指示には感謝しています。そして、はい、bitmapIn = bitmapOrig =オリジナル(後者の2つについては申し訳ありません。 –
@ SamuelAudet:OK、私は[これを]試しました(http://imrannazar.com/Augmented-Reality-with-the-Android-NDK:-Part-2)。結果は、*ほとんど*空白のビットマップ(黒のアーティファクト(黒いランダムなドット)を持つ白い表面)です。他に誰かがこれを撃つのに十分な親切な人ですか? –