- 浏览: 438543 次
文章分类
最新评论
-
barryzhong:
这篇文章挺不错。令人汗颜的是,那可是微软06年的文章。现在都快 ...
推荐一篇关于多租户Multi-Tenant数据架构的文章 -
Mybeautiful:
设计模式只是一个思路或是方案,碰到某种问题是有什么办法比较好的 ...
再见了模式
jni 写一个简单的photoshop
第一步创建ui
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="#ffffffff" > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" > <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnReset" android:text="Reset" android:visibility="visible" android:onClick="onResetImage" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnConvert" android:text="Convert Image" android:visibility="visible" android:onClick="onConvertToGray" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnFindEdges" android:text="Find Edges" android:visibility="visible" android:onClick="onFindEdges" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnDimmer" android:text="- " android:visibility="visible" android:onClick="onDimmer" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnBrighter" android:text=" +" android:visibility="visible" android:onClick="onBrighter" /> </LinearLayout> <ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerCrop" android:layout_gravity="center_vertical|center_horizontal" android:id="@+id/ivDisplay" /> </LinearLayout>
第二步,写activity MainActivity
import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.graphics.BitmapFactory; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; import android.view.View; import android.widget.ImageView; public class IBMPhotoPhun extends Activity { private String tag = "IBMPhotoPhun"; private Bitmap bitmapOrig = null; private Bitmap bitmapGray = null; private Bitmap bitmapWip = null; private ImageView ivDisplay = null; // NDK STUFF static { System.loadLibrary("ibmphotophun"); } public native void convertToGray(Bitmap bitmapIn,Bitmap bitmapOut); public native void changeBrightness(int direction,Bitmap bitmap); public native void findEdges(Bitmap bitmapIn,Bitmap bitmapOut); // END NDK STUFF /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Log.i(tag,"before image stuff"); ivDisplay = (ImageView) findViewById(R.id.ivDisplay); // load bitmap from resources BitmapFactory.Options options = new BitmapFactory.Options(); // Make sure it is 24 bit color as our image processing algorithm // expects this format options.inPreferredConfig = Config.ARGB_8888; bitmapOrig = BitmapFactory.decodeResource(this.getResources(), R.drawable.sampleimage,options); if (bitmapOrig != null) ivDisplay.setImageBitmap(bitmapOrig); } public void onResetImage(View v) { Log.i(tag,"onResetImage"); ivDisplay.setImageBitmap(bitmapOrig); } public void onFindEdges(View v) { Log.i(tag,"onFindEdges"); // make sure our target bitmaps are happy bitmapGray = Bitmap.createBitmap(bitmapOrig.getWidth(),bitmapOrig.getHeight(), Config.ALPHA_8); bitmapWip = Bitmap.createBitmap(bitmapOrig.getWidth(),bitmapOrig.getHeight(), Config.ALPHA_8); // before finding edges, we need to convert this image to gray convertToGray(bitmapOrig,bitmapGray); // find edges in the image findEdges(bitmapGray,bitmapWip); ivDisplay.setImageBitmap(bitmapWip); } public void onConvertToGray(View v) { Log.i(tag,"onConvertToGray"); bitmapWip = Bitmap.createBitmap(bitmapOrig.getWidth(),bitmapOrig.getHeight(), Config.ALPHA_8); convertToGray(bitmapOrig,bitmapWip); ivDisplay.setImageBitmap(bitmapWip); } public void onDimmer(View v) { Log.i(tag,"onDimmer"); changeBrightness(2,bitmapWip); ivDisplay.setImageBitmap(bitmapWip); } public void onBrighter(View v) { Log.i(tag,"onBrighter"); changeBrightness(1,bitmapWip); ivDisplay.setImageBitmap(bitmapWip); } }
Android.mk
LOCAL_PATH := $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE := ibmphotophun LOCAL_SRC_FILES := ibmphotophun.c LOCAL_LDLIBS := -llog -ljnigraphics include $(BUILD_SHARED_LIBRARY)
增加宏
/* * ibmphotophun.c * * Author: Frank Ableson * Contact Info: fableson@msiservices.com */ #include <jni.h> #include <android/log.h> #include <android/bitmap.h> #define LOG_TAG "libibmphotophun" #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__) #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) typedef struct { uint8_t alpha; uint8_t red; uint8_t green; uint8_t blue; } argb; /* convertToGray Pixel operation */ JNIEXPORT void JNICALL Java_com_msi_ibm_ndk_IBMPhotoPhun_convertToGray(JNIEnv * env, jobject obj, jobject bitmapcolor,jobject bitmapgray) { AndroidBitmapInfo infocolor; void* pixelscolor; AndroidBitmapInfo infogray; 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("unlocking pixels"); AndroidBitmap_unlockPixels(env, bitmapcolor); AndroidBitmap_unlockPixels(env, bitmapgray); } /* changeBrightness Pixel Operation */ JNIEXPORT void JNICALL Java_com_msi_ibm_ndk_IBMPhotoPhun_changeBrightness(JNIEnv * env, jobject obj, int direction,jobject bitmap) { AndroidBitmapInfo infogray; void* pixelsgray; int ret; int y; int x; uint8_t save; if ((ret = AndroidBitmap_getInfo(env, bitmap, &infogray)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 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, bitmap, &pixelsgray)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); } // modify pixels with image processing algorithm LOGI("time to modify pixels...."); for (y=0;y<infogray.height;y++) { uint8_t * grayline = (uint8_t *) pixelsgray; int v; for (x=0;x<infogray.width;x++) { v = (int) grayline[x]; if (direction == 1) v -=5; else v += 5; if (v >= 255) { grayline[x] = 255; } else if (v <= 0) { grayline[x] = 0; } else { grayline[x] = (uint8_t) v; } } pixelsgray = (char *) pixelsgray + infogray.stride; } AndroidBitmap_unlockPixels(env, bitmap); } /* findEdges Matrix operation */ JNIEXPORT void JNICALL Java_com_msi_ibm_ndk_IBMPhotoPhun_findEdges(JNIEnv * env, jobject obj, jobject bitmapgray,jobject bitmapedges) { AndroidBitmapInfo infogray; void* pixelsgray; AndroidBitmapInfo infoedges; void* pixelsedge; int ret; int y; int x; int sumX,sumY,sum; int i,j; int Gx[3][3]; int Gy[3][3]; uint8_t *graydata; uint8_t *edgedata; LOGI("findEdges running"); Gx[0][0] = -1;Gx[0][1] = 0;Gx[0][2] = 1; Gx[1][0] = -2;Gx[1][1] = 0;Gx[1][2] = 2; Gx[2][0] = -1;Gx[2][1] = 0;Gx[2][2] = 1; Gy[0][0] = 1;Gy[0][1] = 2;Gy[0][2] = 1; Gy[1][0] = 0;Gy[1][1] = 0;Gy[1][2] = 0; Gy[2][0] = -1;Gy[2][1] = -2;Gy[2][2] = -1; if ((ret = AndroidBitmap_getInfo(env, bitmapgray, &infogray)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); return; } if ((ret = AndroidBitmap_getInfo(env, bitmapedges, &infoedges)) < 0) { LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret); 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; } LOGI("color image :: width is %d; height is %d; stride is %d; format is %d;flags is %d",infoedges.width,infoedges.height,infoedges.stride,infoedges.format,infoedges.flags); if (infoedges.format != ANDROID_BITMAP_FORMAT_A_8) { LOGE("Bitmap format is not A_8 !"); return; } if ((ret = AndroidBitmap_lockPixels(env, bitmapgray, &pixelsgray)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); } if ((ret = AndroidBitmap_lockPixels(env, bitmapedges, &pixelsedge)) < 0) { LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret); } // modify pixels with image processing algorithm LOGI("time to modify pixels...."); graydata = (uint8_t *) pixelsgray; edgedata = (uint8_t *) pixelsedge; for (y=0;y<=infogray.height - 1;y++) { for (x=0;x<infogray.width -1;x++) { sumX = 0; sumY = 0; // check boundaries if (y==0 || y == infogray.height-1) { sum = 0; } else if (x == 0 || x == infogray.width -1) { sum = 0; } else { // calc X gradient for (i=-1;i<=1;i++) { for (j=-1;j<=1;j++) { sumX += (int) ( (*(graydata + x + i + (y + j) * infogray.stride)) * Gx[i+1][j+1]); } } // calc Y gradient for (i=-1;i<=1;i++) { for (j=-1;j<=1;j++) { sumY += (int) ( (*(graydata + x + i + (y + j) * infogray.stride)) * Gy[i+1][j+1]); } } sum = abs(sumX) + abs(sumY); } if (sum>255) sum = 255; if (sum<0) sum = 0; *(edgedata + x + y*infogray.width) = 255 - (uint8_t) sum; } } AndroidBitmap_unlockPixels(env, bitmapgray); AndroidBitmap_unlockPixels(env, bitmapedges); }
相关推荐
Android JNI Android JNI 用C函数写本地库读写文件,底层调用小例子用C函数写本地库读写文件,底层调用小例子
简单实现JNIdemo简单实现JNIdemo简单实现JNIdemo简单实现JNIdemo
java使用JNI调用c++代码的实例,主要实现了在java环境中利用c++下的写文件流操作写一个本地文件,可以作为JNI基本配置上手的参考。
JAVA使用JNI读写INI文件的实例。 JAVA本身并没有读写INI文件的现成方法,有些人自己编写方法来读写INI文件,但是这样的方法或多或少的存在着一些问题。此示例旨在利用本地的WIN32API函数来读写INI文件,这样可以保证...
用jni写的一个hello world程序
使用动态注册的方法写一个最简单的hello-jni程序
JNI攻略之一――建立一个简单的JNI程序
一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放...
一个基本的Android jni程序
这个是一个简单的JNI小实验,提供完整的过程附图以及实验成功,一看即懂!
1、 第二章通过一个简单的例子介绍了JNI。它的对象是对JNI不熟悉的初学者。 2、 3~10章对JNI的特征进行了系统的介绍。我们会举大量的例子来说明JNI的各个特征,这些特征都是JNI中重要且常用的。 3、 11~13章是关于...
学习JNI编译时,缺少的jni.h和jni_md.h头文件,Java调用C和C++函数时的JNI使用区别: 注意:jni.h头文件中对于***.c & ***.cpp采用不同的定义
JNI的两个头文件jni.h和jni_md.h,提供需要的人下载!!!!!
代码用来演示第一个jni实例!对初学者很实用!
JNI 是 JAVA 平台的一个重要特征, 使用它我们可以至用以前用 C/C++写的大量代码。本书 既是一个编程指南也是一个 JNI 手册。本书共包括三部分: 1 、 第二章通过一个简单的例子介绍了 JNI。它的对象是对 JNI 不...
Android Studio下NDK开发最简单的JNI实例demo,最少的代码量调通完整jni。
jniDemo是一个jni小工程,意在学习在工程中引入jni。
http://blog.csdn.net/lgl1170860350/article/details/51006595 一个简单的jni显示Dialog的例子
整理的一个简洁的JNI实例,每一步都能够通俗易懂,可以迅速了解jni的用法
NULL 博文链接:https://jxjjhz.iteye.com/blog/1061489