• Android NDK Bitmap to gray


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

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

          

    从转换灰度图的耗时来说,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)
  • 相关阅读:
    spring源码分析之cache注解
    Full Gc经历分析
    spring源码分析之context
    spring源码分析之freemarker整合
    publishing failed with multiple errors resource is out of sync with the file system--转
    真正解决问题:maven eclipse tomcat java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener--转
    pyspark kafka createDirectStream和createStream 区别
    kafka 0.11 spark 2.11 streaming例子
    蜜罐技术——通过布置一些作为诱饵的主机、网络服务或者信息,诱使攻击方对它们实施攻击,从而可以对攻击行为进行捕获和分析
    安装和使用访问暗网
  • 原文地址:https://www.cnblogs.com/qiengo/p/2597518.html
Copyright © 2020-2023  润新知