gpt4 book ai didi

android - native 位图处理和 ALPHA_8

转载 作者:塔克拉玛干 更新时间:2023-11-02 21:18:27 25 4
gpt4 key购买 nike

我正在尝试通过 native 函数将图像转换为灰度,使用的一段代码取自 Android in Action(第 2 版;您还可以查看 here)。不幸的是,返回的位图对象最终为空,而不是灰度。

这是我加载 (.png) 图像的方式:

Bitmap original = BitmapFactory.decodeResource(this.getResources(), R.drawable.sample, options);

位图通过了许多安全条件(请在下面检查)。这是 Java 中的 native 函数定义:

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。使用此版本,当从主线程 调用 native 代码时,该函数会起作用。在 2.3 模拟器上,不管调用 C 代码的线程如何,或者位图的加载方式如何,该函数都不起作用。 Android NDK:4b 和 6b。

UPDATE #1: You'll find the complete source code here.

UPDATE #2: RGB_565 instead of ALPHA_8 gives some results. It appears not even setPixels() in Java works for ALPHA_8, and I'm having problems finding info on this config type. Any kind of help would be much appreciated.

最佳答案

我遇到了类似的问题。首先,我为 infogray 使用了 android RGBA_8888 格式而不是 A_8(原始位图是使用 ARGB_8888 格式创建的)。然后,如果您使用 argb 结构而不是 uint_8 作为灰线,则可以像这样填充像素:

for (y = 0; y < infocolor.height; ++y) {
argb* line = (argb*) pixelscolor;
argb* grayline = (argb*) pixelsgray;
for (x = 0; x < infocolor.width; ++x) {
grayline[x].red = grayline[x].green = grayline[x].blue = 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;
}

关于android - native 位图处理和 ALPHA_8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7623382/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com