sto cercando di convertire un'immagine in scala di grigi con una funzione nativa, utilizzando un pezzo di codice preso da Android in azione (2a ed .; si può anche vedere here). Sfortunatamente, l'oggetto bitmap restituito, anziché la scala di grigi, finisce vuoto.nativo di elaborazione bitmap e ALPHA_8
Questo è come mi caricare l'immagine (.png):
Bitmap original = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample, options);
C'è un certo numero di condizioni di sicurezza che il bitmap passa (si prega di controllare qui di seguito). Ecco la definizione nativa funzione in Java:
public native void convertToGray(Bitmap bitmapIn,Bitmap bitmapOut);
e la chiamata:
// Grayscale bitmap (initially empty)
Bitmap gray = Bitmap.createBitmap(original.getWidth(),original.getHeight(),Config.ALPHA_8);
// Native function call
convertToGray(original,gray);
Ed ecco la funzione:
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);
}
La bitmap colore viene passato in modo corretto, e la parte di elaborazione di il codice sembra funzionare correttamente, ma bitmapgray rimane vuoto. Immagino che mi manchi qualcosa di cruciale qui.
Ambiente di test: emulatore, v2.2. Con questa versione, la funzione funziona quando viene chiamato il codice nativo dal thread principale . Su un emulatore 2.3, la funzione non funziona indipendentemente dal thread che chiama il codice C o il modo in cui viene caricata la bitmap. NDK Android: 4b & 6b.
UPDATE # 1: Troverete il codice sorgente completo here.
UPDATE # 2: RGB_565 invece di ALPHA_8 fornisce alcuni risultati. Sembra che nemmeno setPixels() in Java funzioni per ALPHA_8 e sto riscontrando problemi con per trovare informazioni su questo tipo di configurazione. Ogni tipo di aiuto sarebbe molto apprezzato.
Avete preso in considerazione cercando di utilizzare un ByteBuffer come output? Se funziona, potremmo essere più sicuri che ci sia qualcosa di sbagliato in AndroidBitmap ... Inoltre sono 'bitmapIn',' bitmapOrig' e 'original' lo stesso oggetto? –
Sono completamente nuovo a JNI, quindi no, non l'ho provato. Darò un colpo e poi riferire. Sarei ancora grato per alcuni suggerimenti o indicazioni che potrebbero accelerare il processo. E sì, bitmapIn = bitmapOrig = original (mi dispiace per gli ultimi due, avrei dovuto renderlo più chiaro, corretto). –
@ SamuelAudet: OK, ho provato [questo] (http://imrannazar.com/Augmented-Reality-with-the-Android-NDK:-Part-2). Il risultato è un bitmap * quasi * vuoto (una superficie bianca con artefatti neri (punti neri casuali)). Qualcun altro sarebbe così gentile da dare una possibilità? –