#include "PhotoProcessingActivity.h"
JNIEXPORT void JNICALL Java_com_example_photoprocessing_activity_PhotoProcessingActivity_grayPhoto(
JNIEnv *env, jobject photoProcessingActivity, jobject bmOriginal,
jobject bmGray) {
AndroidBitmapInfo origanalColor;
void* pixelscolor;
AndroidBitmapInfo infogray;
void* pixelsgray;
int ret;
int y;
int x;
LOGI("In convertToGray");
if ((ret = AndroidBitmap_getInfo(env, bmOriginal, &origanalColor)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
if ((ret = AndroidBitmap_getInfo(env, bmGray, &infogray)) < 0) {
LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
return;
}
LOGI(
"original image :: width is %d; height is %d; stride is %d; format is %d;flags is %d,stride is %u", origanalColor.width, origanalColor.height, origanalColor.stride, origanalColor.format, origanalColor.flags, origanalColor.stride);
if (origanalColor.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
LOGE("Bitmap format is not RGBA_8888 !");
//return;
}
if (origanalColor.format == ANDROID_BITMAP_FORMAT_RGB_565) {
LOGI("Original Image is ANDROID_BITMAP_FORMAT_RGB_565");
if ((ret = AndroidBitmap_lockPixels(env, bmOriginal, &pixelscolor))
< 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
if ((ret = AndroidBitmap_lockPixels(env, bmGray, &pixelsgray)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
// modify pixels with image processing algorithm
for (y = 0; y < origanalColor.height; y++) {
__uint16_t * line = (__uint16_t *) pixelscolor;
uint8_t * grayline = (uint8_t *) pixelsgray;
for (x = 0; x < origanalColor.width; x++) {
grayline[x] = (uint8_t)(((line[x] >> 11 <<3) + (line[x] >> 5 & 63 * 16) + (line[x]&31 * 8)) / 3);
//LOGI("%d %d %d %d",line[x].alpha,line[x].red,line[x].green,line[x].blue);
/*if(x ==0){
LOGI("line:%o grayline %o ",line[x],grayline[x]);
}*/
}
pixelscolor = (char *) pixelscolor + origanalColor.stride;
pixelsgray = (char *) pixelsgray + infogray.stride;
}
LOGI("unlocking pixels");
AndroidBitmap_unlockPixels(env, bmOriginal);
AndroidBitmap_unlockPixels(env, bmGray);
LOGI("Return !! ");
return ;
}
LOGI(
"gray image :: width is %d; height is %d; stride is %d; format is %d;flags is %d %d,stride is %u", infogray.width, infogray.height, infogray.stride, infogray.format, infogray.flags, infogray.stride);
if (infogray.format != ANDROID_BITMAP_FORMAT_A_8) {
LOGE("Bitmap format is not A_8 !");
return;
}
if ((ret = AndroidBitmap_lockPixels(env, bmOriginal, &pixelscolor)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
if ((ret = AndroidBitmap_lockPixels(env, bmGray, &pixelsgray)) < 0) {
LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
}
// modify pixels with image processing algorithm
for (y = 0; y < origanalColor.height; y++) {
argb * line = (argb *) pixelscolor;
uint8_t * grayline = (uint8_t *) pixelsgray;
for (x = 0; x < origanalColor.width; x++) {
grayline[x] = (line[x].red + line[x].green + line[x].blue) / 3;
}
pixelscolor = (char *) pixelscolor + origanalColor.stride;
pixelsgray = (char *) pixelsgray + infogray.stride;
}
LOGI("unlocking pixels");
AndroidBitmap_unlockPixels(env, bmOriginal);
AndroidBitmap_unlockPixels(env, bmGray);
}
编写Android.mk文件,该文件主要是指明要使用的.so文件,并且生成我们自己的.so文件
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := PhotoProcessing LOCAL_SRC_FILES := PhotoProcessing.cpp LOCAL_LDLIBS := -llog -ljnigraphics include $(BUILD_SHARED_LIBRARY)关键的一些代码就是这些了,其中处理的灰度算法可能不是非常优化,这其中处理RGB565部分是我自己根据图像处理中灰度的定义所写的,其中也要感谢孙志海大哥对我的帮助 !!
可以说使用这种方法还是比较简易的,但是,似乎仍没解决我一开头说道的问题,即这种方式仅仅是提升了程序的效率,但依然需要在UI线程中更新界面,这里也可以使用SurfaceVIew来进行异步的更新界面,但是这里,我想知道,在不修改android系统源码情况下,NDK的极限,即它能否直接控制View的surface,使其不通过java代码就直接把界