`
haierboos
  • 浏览: 438543 次
文章分类
社区版块
存档分类
最新评论

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 用C函数写本地库读写文件,底层调用小例子

    Android JNI Android JNI 用C函数写本地库读写文件,底层调用小例子用C函数写本地库读写文件,底层调用小例子

    简单的JNIdemo

    简单实现JNIdemo简单实现JNIdemo简单实现JNIdemo简单实现JNIdemo

    JNi调用c++写本地文件小例子

    java使用JNI调用c++代码的实例,主要实现了在java环境中利用c++下的写文件流操作写一个本地文件,可以作为JNI基本配置上手的参考。

    JAVA使用JNI读写INI文件

    JAVA使用JNI读写INI文件的实例。 JAVA本身并没有读写INI文件的现成方法,有些人自己编写方法来读写INI文件,但是这样的方法或多或少的存在着一些问题。此示例旨在利用本地的WIN32API函数来读写INI文件,这样可以保证...

    用JNI写的Hello world程序

    用jni写的一个hello world程序

    动态注册JNI方法写hello jni

    使用动态注册的方法写一个最简单的hello-jni程序

    JNI攻略之一――建立一个简单的JNI程序

    JNI攻略之一――建立一个简单的JNI程序

    jni简单的例子,初学者一看就会

    一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放到桌面直接编译就能跑,一个jni例子,放...

    第一个JNI程序

    一个基本的Android jni程序

    一个简单的JNI实验

    这个是一个简单的JNI小实验,提供完整的过程附图以及实验成功,一看即懂!

    JNI编程指南书

    1、 第二章通过一个简单的例子介绍了JNI。它的对象是对JNI不熟悉的初学者。 2、 3~10章对JNI的特征进行了系统的介绍。我们会举大量的例子来说明JNI的各个特征,这些特征都是JNI中重要且常用的。 3、 11~13章是关于...

    jni.zip jni编译jni下载

    学习JNI编译时,缺少的jni.h和jni_md.h头文件,Java调用C和C++函数时的JNI使用区别: 注意:jni.h头文件中对于***.c & ***.cpp采用不同的定义

    JNI的两个头文件jni.h和jni_md.h

    JNI的两个头文件jni.h和jni_md.h,提供需要的人下载!!!!!

    第一个JNI实例学习

    代码用来演示第一个jni实例!对初学者很实用!

    JNI编程指南-书签版

    JNI 是 JAVA 平台的一个重要特征, 使用它我们可以至用以前用 C/C++写的大量代码。本书 既是一个编程指南也是一个 JNI 手册。本书共包括三部分: 1 、 第二章通过一个简单的例子介绍了 JNI。它的对象是对 JNI 不...

    Jni最简单的实例demo

    Android Studio下NDK开发最简单的JNI实例demo,最少的代码量调通完整jni。

    jniDemo简单版

    jniDemo是一个jni小工程,意在学习在工程中引入jni。

    一个简单的jni显示Dialog的例子

    http://blog.csdn.net/lgl1170860350/article/details/51006595 一个简单的jni显示Dialog的例子

    JNI简单实例

    整理的一个简洁的JNI实例,每一步都能够通俗易懂,可以迅速了解jni的用法

    JNI实现示例DEMO

    NULL 博文链接:https://jxjjhz.iteye.com/blog/1061489

Global site tag (gtag.js) - Google Analytics