Android NDK Bitmap to gray

Source:http://blog.csdn.net/hellogv/archive/2010/12/23/6094127.aspx

 在Android上使用JAVA实现彩图转换为灰度图,跟J2ME上的实现类似,不过遇到频繁地转换或者是大图转换时,就必须使用NDK来提高速度了。本文主要通过JAVA和NDK这两种方式来分别实现彩图转换为灰度图,并给出速度的对比。

      Android NDK Bitmap to gray

从转换灰度图的耗时来说,NDK的确比JAVA所用的时间短不少。

主程序testToGray.java的源码如下:

package com.testToGray;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Bitmap.Config;

import android.graphics.drawable.BitmapDrawable;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.ImageView;

public class testToGray extends Activity {

    /** Called when the activity is first created. */

    Button btnJAVA,btnNDK;

    ImageView imgView;

    @Override

    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        this.setTitle("使用NDK转换灰度图---hellogv");

        btnJAVA=(Button)this.findViewById(R.id.btnJAVA);

        btnJAVA.setOnClickListener(new ClickEvent());

        

        btnNDK=(Button)this.findViewById(R.id.btnNDK);

        btnNDK.setOnClickListener(new ClickEvent());

        imgView=(ImageView)this.findViewById(R.id.ImageView01);

    }

    class ClickEvent implements View.OnClickListener{

        @Override

        public void onClick(View v) {

            if(v==btnJAVA)

            {

                long current=System.currentTimeMillis();

                Bitmap img=ConvertGrayImg(R.drawable.cat);

                long performance=System.currentTimeMillis()-current;

                //显示灰度图

                imgView.setImageBitmap(img);

                testToGray.this.setTitle("w:"+String.valueOf(img.getWidth())+",h:"+String.valueOf(img.getHeight())

                        +" JAVA耗时 "+String.valueOf(performance)+" 毫秒");

            }

            else if(v==btnNDK)

            {

                long current=System.currentTimeMillis();

                

                //先打开图像并读取像素

                Bitmap img1=((BitmapDrawable) getResources().getDrawable(R.drawable.cat)).getBitmap();

                int w=img1.getWidth(),h=img1.getHeight();

                int[] pix = new int[w * h];

                img1.getPixels(pix, 0, w, 0, 0, w, h);

                //通过ImgToGray.so把彩色像素转为灰度像素

                int[] resultInt=LibFuns.ImgToGray(pix, w, h);

                Bitmap resultImg=Bitmap.createBitmap(w, h, Config.RGB_565);

                resultImg.setPixels(resultInt, 0, w, 0, 0,w, h);

                long performance=System.currentTimeMillis()-current;

                //显示灰度图

                imgView.setImageBitmap(resultImg);

                testToGray.this.setTitle("w:"+String.valueOf(img1.getWidth())+",h:"+String.valueOf(img1.getHeight())

                        +" NDK耗时 "+String.valueOf(performance)+" 毫秒");

            }

        }

    }

    

    /**

     * 把资源图片转为灰度图

     * @param resID 资源ID

     * @return

     */

    public Bitmap ConvertGrayImg(int resID)

    {

        Bitmap img1=((BitmapDrawable) getResources().getDrawable(resID)).getBitmap();

        

        int w=img1.getWidth(),h=img1.getHeight();

        int[] pix = new int[w * h];

        img1.getPixels(pix, 0, w, 0, 0, w, h);

        

        int alpha=0xFF<<24;

        for (int i = 0; i < h; i++) {  

            for (int j = 0; j < w; j++) {  

                // 获得像素的颜色  

                int color = pix[w * i + j];  

                int red = ((color & 0x00FF0000) >> 16);  

                int green = ((color & 0x0000FF00) >> 8);  

                int blue = color & 0x000000FF;  

                color = (red + green + blue)/3;  

                color = alpha | (color << 16) | (color << 8) | color;  

                pix[w * i + j] = color;

            }

        }

        Bitmap result=Bitmap.createBitmap(w, h, Config.RGB_565);

        result.setPixels(pix, 0, w, 0, 0,w, h);

        return result;

    }

}

封装NDK函数的JAVA类LibFuns.java的源码如下:

package com.testToGray;

public class LibFuns {

    static {

        System.loadLibrary("ImgToGray");

    }

   /**

    * @param width the current view width

    * @param height the current view height

    */

    

    public static native int[] ImgToGray(int[] buf, int w, int h);

}

彩图转换为灰度图的ImgToGray.cpp源码:

#include <jni.h>

#include <stdio.h>

#include <stdlib.h>

extern "C" {

JNIEXPORT jintArray JNICALL Java_com_testToGray_LibFuns_ImgToGray(

        JNIEnv* env, jobject obj, jintArray buf, int w, int h);

}

;

JNIEXPORT jintArray JNICALL Java_com_testToGray_LibFuns_ImgToGray(

        JNIEnv* env, jobject obj, jintArray buf, int w, int h) {

    jint *cbuf;

    cbuf = env->GetIntArrayElements(buf, false);

    if (cbuf == NULL) {

        return 0; /* exception occurred */

    }

    int alpha = 0xFF << 24;

    for (int i = 0; i < h; i++) {

        for (int j = 0; j < w; j++) {

            // 获得像素的颜色

            int color = cbuf[w * i + j];

            int red = ((color & 0x00FF0000) >> 16);

            int green = ((color & 0x0000FF00) >> 8);

            int blue = color & 0x000000FF;

            color = (red + green + blue) / 3;

            color = alpha | (color << 16) | (color << 8) | color;

            cbuf[w * i + j] = color;

        }

    }

    int size=w * h;

    jintArray result = env->NewIntArray(size);

    env->SetIntArrayRegion(result, 0, size, cbuf);

    env->ReleaseIntArrayElements(buf, cbuf, 0);

    return result;

}

Android.mk的源码:

LOCAL_PATH:= $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := ImgToGray

LOCAL_SRC_FILES := ImgToGray.cpp

include $(BUILD_SHARED_LIBRARY)

你可能感兴趣的:(android NDK)