Я пытаюсь преобразовать изображение в оттенки серого с помощью встроенной функции, используя фрагмент кода, взятый из Android в действии (2-е изд .; вы также можете увидеть его здесь ). К сожалению, возвращенный растровый объект вместо градаций серого оказывается пустым.
Вот как я загружаю (.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 остается пустой. Я полагаю, что здесь что-то упущено.
Тестовая среда: эмулятор, v2.2. В этой версии функция работает, когда собственный код вызывается из основного потока . В эмуляторе 2.3 функция не работает независимо от потока , который вызывает код C, или способа загрузки растрового изображения. Android NDK: 4b и 6b.
ОБНОВЛЕНИЕ № 1: Вы найдете полный исходный код здесь .
ОБНОВЛЕНИЕ № 2: RGB_565 вместо ALPHA_8 дает некоторые результаты. Похоже, даже setPixels () в Java не работает для ALPHA_8, и я имею
Проблемы с поиском информации по этому типу конфигурации. Любая помощь будет
высоко ценится.