zoukankan      html  css  js  c++  java
  • 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);
    
        
    }



  • 相关阅读:
    Can't remove netstandard folder from output path (.net standard)
    website项目的reference问题
    The type exists in both DLLs
    git常用配置
    Map dependencies with code maps
    How to check HTML version of any website
    Bootstrap UI 编辑器
    网上职位要求对照
    Use of implicitly declared global variable
    ResolveUrl in external JavaScript file in asp.net project
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3241163.html
Copyright © 2011-2022 走看看