Estoy tratando de convertir una imagen a escala de grises a través de una función nativa, usando un código tomado de Android en Acción (2nd ed. También puede verlo here). Desafortunadamente, el objeto de mapa de bits devuelto, en lugar de la escala de grises, termina vacío.Procesamiento de mapa de bits nativo y ALPHA_8
Así es como me carga la imagen (.png):
Bitmap original = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample, options);
Hay una serie de condiciones de seguridad que pasa el mapa de bits (por favor, consulte más abajo). Esta es la definición nativa función en Java:
public native void convertToGray(Bitmap bitmapIn,Bitmap bitmapOut);
y la llamada:
// Grayscale bitmap (initially empty)
Bitmap gray = Bitmap.createBitmap(original.getWidth(),original.getHeight(),Config.ALPHA_8);
// Native function call
convertToGray(original,gray);
y aquí está la función:
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);
}
El mapa de bits de color se transmite correctamente, y la parte de procesamiento de el código parece estar funcionando bien, pero bitmapgray permanece vacío. Creo que me estoy perdiendo algo crucial aquí.
Entorno de prueba: emulador, v2.2. Con esta versión, la función funciona cuando se llama al código nativo desde el hilo principal . En un emulador 2.3, la función no funciona independientemente del hilo que llama al código C, o la forma en que se carga el mapa de bits. Android NDK: 4b & 6b.
ACTUALIZACIÓN # 1: Encontrará el código fuente completo here.
ACTUALIZACIÓN # 2: RGB_565 en lugar de ALPHA_8 da algunos resultados. Parece que ni siquiera setPixels() en Java funciona para ALPHA_8, y estoy teniendo problemas para encontrar información sobre este tipo de configuración. Cualquier tipo de ayuda sería muy apreciada.
¿Usted ha considerado que intenta utilizar un ByteBuffer como salida? Si eso funciona, entonces podríamos estar más seguros de que hay algo mal con AndroidBitmap ... ¿También están 'bitmapIn',' bitmapOrig' y 'original' el mismo objeto? –
Soy completamente nuevo en JNI, así que no, no lo he probado. Le daré una oportunidad y luego informaré. Todavía estaría agradecido por algunos consejos o indicaciones que podrían acelerar el proceso. Y sí, bitmapIn = bitmapOrig = original (lo siento por los dos últimos, debería haberlo aclarado, haberlo solucionado). –
@SamuelAudet: Bien, probé [este] (http://imrannazar.com/Augmented-Reality-with-the-Android-NDK:-Part-2). El resultado es un mapa de bits * casi * en blanco (una superficie blanca con artefactos negros (puntos negros al azar)). ¿Alguien más sería tan amable de dar una oportunidad? –