Android提高之使用NDK把彩图转换灰度图的方法
一般而言在Android上使用JAVA实现彩图转换为灰度图,与J2ME上的实现方法类似,不过遇到频繁地转换或者是大图转换时,就必须使用NDK来提高速度了。本文主要通过JAVA和NDK这两种方式来分别实现彩图转换为灰度图,并给出速度的对比,供大家参考。
先来简单地介绍一下Android的NDK使用步骤:
以NDKr4为例,或许以后新版的NDK的使用方法略有不同。
1、下载支持C++的android-ndk-r4-crystax,支持C++的话可玩性更强。
2、下载cygwin,选择ftp://mirrors.kernel.org这个镜像,搜索 DevelInstall安装gcc和make等工具;
如图所示:
在搜索框里分别搜索gcc和make,必须是DevelInstall栏的。
3、Cygwin安装目录下,找到home/username的目录下的.bash_profile文件,打开文件在最后加上:
NDK=/cygdrive/d:cygwin/android-ndk-r4-crystax
exportNDK
PS:假设安装在D:/cygwin/android-ndk-r4-crystax。
4、运行cygwin,通过cd命令去到NDK/samples/例子目录/,运行$NDK/ndk-build来编译该目录下的Android.mk
以下是个人习惯
5、安装Eclipse的CDT,官方下载cdt安装包,解压缩后把plugins和feagures复制覆盖到eclipse文件夹下即可
6、去到系统属性->环境变量->Path添加"D:/cygwin/bin"(假设cygwin安装在D:下)和"D:/cygwin/android-ndk-r4-crystax",重启计算机,然后就可以在Eclipse里面建立基于cygwin的C/C++工程了,先通过这一步来验证NDK的程序能够编译成功,然后再通过第4步来生成SO文件。
接下来看看本文程序运行的效果:
从转换灰度图的耗时来说,NDK的确比JAVA所用的时间短不少。
main.xml源码如下:
<?xmlversion="1.0"encoding="utf-8"?> -<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="fill_parent"android:layout_height="fill_parent"> <Buttonandroid:layout_height="wrap_content"android:layout_width="fill_parent"android:id="@+id/btnJAVA"android:text="使用JAVA转换灰度图"/> <Buttonandroid:layout_height="wrap_content"android:layout_width="fill_parent"android:id="@+id/btnNDK"android:text="使用NDK转换灰度图"/> <ImageViewandroid:id="@+id/ImageView01"android:layout_width="fill_parent"android:layout_height="fill_parent"/> </LinearLayout>
主程序testToGray.java的源码如下:
packagecom.testToGray; importandroid.app.Activity; importandroid.graphics.Bitmap; importandroid.graphics.Bitmap.Config; importandroid.graphics.drawable.BitmapDrawable; importandroid.os.Bundle; importandroid.view.View; importandroid.widget.Button; importandroid.widget.ImageView; publicclasstestToGrayextendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ ButtonbtnJAVA,btnNDK; ImageViewimgView; @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); this.setTitle("使用NDK转换灰度图---hellogv"); btnJAVA=(Button)this.findViewById(R.id.btnJAVA); btnJAVA.setOnClickListener(newClickEvent()); btnNDK=(Button)this.findViewById(R.id.btnNDK); btnNDK.setOnClickListener(newClickEvent()); imgView=(ImageView)this.findViewById(R.id.ImageView01); } classClickEventimplementsView.OnClickListener{ @Override publicvoidonClick(Viewv){ if(v==btnJAVA) { longcurrent=System.currentTimeMillis(); Bitmapimg=ConvertGrayImg(R.drawable.cat); longperformance=System.currentTimeMillis()-current; //显示灰度图 imgView.setImageBitmap(img); testToGray.this.setTitle("w:"+String.valueOf(img.getWidth())+",h:"+String.valueOf(img.getHeight()) +"JAVA耗时"+String.valueOf(performance)+"毫秒"); } elseif(v==btnNDK) { longcurrent=System.currentTimeMillis(); //先打开图像并读取像素 Bitmapimg1=((BitmapDrawable)getResources().getDrawable(R.drawable.cat)).getBitmap(); intw=img1.getWidth(),h=img1.getHeight(); int[]pix=newint[w*h]; img1.getPixels(pix,0,w,0,0,w,h); //通过ImgToGray.so把彩色像素转为灰度像素 int[]resultInt=LibFuns.ImgToGray(pix,w,h); BitmapresultImg=Bitmap.createBitmap(w,h,Config.RGB_565); resultImg.setPixels(resultInt,0,w,0,0,w,h); longperformance=System.currentTimeMillis()-current; //显示灰度图 imgView.setImageBitmap(resultImg); testToGray.this.setTitle("w:"+String.valueOf(img1.getWidth())+",h:"+String.valueOf(img1.getHeight()) +"NDK耗时"+String.valueOf(performance)+"毫秒"); } } } /** *把资源图片转为灰度图 *@paramresID资源ID *@return */ publicBitmapConvertGrayImg(intresID) { Bitmapimg1=((BitmapDrawable)getResources().getDrawable(resID)).getBitmap(); intw=img1.getWidth(),h=img1.getHeight(); int[]pix=newint[w*h]; img1.getPixels(pix,0,w,0,0,w,h); intalpha=0xFF<<24; for(inti=0;i<h;i++){ for(intj=0;j<w;j++){ //获得像素的颜色 intcolor=pix[w*i+j]; intred=((color&0x00FF0000)>>16); intgreen=((color&0x0000FF00)>>8); intblue=color&0x000000FF; color=(red+green+blue)/3; color=alpha|(color<<16)|(color<<8)|color; pix[w*i+j]=color; } } Bitmapresult=Bitmap.createBitmap(w,h,Config.RGB_565); result.setPixels(pix,0,w,0,0,w,h); returnresult; } }
封装NDK函数的JAVA类LibFuns.java的源码如下:
packagecom.testToGray; publicclassLibFuns{ static{ System.loadLibrary("ImgToGray"); } /** *@paramwidththecurrentviewwidth *@paramheightthecurrentviewheight */ publicstaticnativeint[]ImgToGray(int[]buf,intw,inth); }
彩图转换为灰度图的ImgToGray.cpp源码:
#include<jni.h> #include<stdio.h> #include<stdlib.h> extern"C"{ JNIEXPORTjintArrayJNICALLJava_com_testToGray_LibFuns_ImgToGray( JNIEnv*env,jobjectobj,jintArraybuf,intw,inth); } ; JNIEXPORTjintArrayJNICALLJava_com_testToGray_LibFuns_ImgToGray( JNIEnv*env,jobjectobj,jintArraybuf,intw,inth){ jint*cbuf; cbuf=env->GetIntArrayElements(buf,false); if(cbuf==NULL){ return0;/*exceptionoccurred*/ } intalpha=0xFF<<24; for(inti=0;i<h;i++){ for(intj=0;j<w;j++){ //获得像素的颜色 intcolor=cbuf[w*i+j]; intred=((color&0x00FF0000)>>16); intgreen=((color&0x0000FF00)>>8); intblue=color&0x000000FF; color=(red+green+blue)/3; color=alpha|(color<<16)|(color<<8)|color; cbuf[w*i+j]=color; } } intsize=w*h; jintArrayresult=env->NewIntArray(size); env->SetIntArrayRegion(result,0,size,cbuf); env->ReleaseIntArrayElements(buf,cbuf,0); returnresult; }
Android.mk的源码:
LOCAL_PATH:=$(callmy-dir) include$(CLEAR_VARS) LOCAL_MODULE:=ImgToGray LOCAL_SRC_FILES:=ImgToGray.cpp include$(BUILD_SHARED_LIBRARY)
感兴趣的读者可以动手调试一下本文所述代码,相信会对大家进行Android项目开发有一定的帮助。
相关文章
- Android telephony_android获取真实时间
- android 置灰不可点击,Android Studio 运行按钮灰色的完美解决方法
- android onresume方法,非静态方法’onResume’Android Studio
- android开机动画多长时间_Android开机动画及黑屏[通俗易懂]
- android 浏览器 开发,Android 浏览器的开发实例分享
- android activity自动跳转,Android activity跳转之finish()方法的作用
- android开发笔记之 Android代码混淆打包
- android app 退出功能,Android 完美退出 App (Exit)
- mac 电脑android环境变量设置,mac上Android环境变量配置[通俗易懂]
- 【Android布局】在程序中设置android gravity 和 android layout Gravity属性
- android toast显示时间,Android Toast自定义显示时间「建议收藏」
- Android angle_android 界面悬停
- android触摸屏事件,Android Touch事件分析
- android进程间通信的方式_Android进程注入
- 【Android NDK 开发】JNI 方法解析 ( int 数组传递 | jintArray 类型 | 数组转换 | 获取数组长度 | 获取数组元素 | 指针遍历数组 | 数组返回值设置 )
- 【Android NDK 开发】JNI 方法解析 ( 字符串数组参数传递 | 字符串遍历 | 类型强转 | Java 字符串与 C 字符串转换 | 字符串释放 )
- 【Android 内存优化】Bitmap 图像尺寸缩小 ( 设置 Options 参数 | inJustDecodeBounds | inSampleSize | 工具类实现 )
- 【Android 逆向】ptrace 函数 ( ptrace 函数族 | 进程附着 | 进程脱离 | 进程数据读写权限 | 进程对应的主线程寄存器读写 | 单步调试 |ptrace 函数族状态转换 )
- 【Android Gradle 插件】将自定义 Gradle 插件上传到自建 Maven 仓库 ③ ( 配置上传工件 | 将 Gradle 插件 jar 包、源码、文档上传到本地Maven 仓库 )
- Android MVP详解手机开发
- [android] 看博客学习Android常见的几种RuntimeException详解手机开发
- Android Studio 导入项目 出现安装Error:Cause: failed to find target with hash string ‘android-23’ 等错误详解手机开发
- Android操作SQLite数据库详解编程语言
- Wine On Android将可以在Android上运行Windows程序
- Connecting Android to Oracle: The Ultimate Guide for Seamless Integration.(android连接oracle)
- Android第三方应用接入微信平台研究情况分享(二)
- Android系统自带样式(android:theme)