本文来自http://blog.csdn.net/hellogv/,引用必须注明出处!
在Android上使用JAVA实现彩图转换为灰度图,跟J2ME上的实现类似,不过遇到频繁地转换或者是大图转换时,就必须使用NDK来提高速度了。本文主要通过JAVA和NDK这两种方式来分别实现彩图转换为灰度图,并给出速度的对比。
先来简单地介绍一下Android的NDK使用步骤:
以NDK
r4为例,或许以后新版的NDK的使用方法略有不同。
1、下载支持C++的android-ndk-r4-crystax,支持C++的话可玩性更强......
2、下载cygwin,选择ftp://mirrors.kernel.org这个镜像,搜索
Devel Install 安装 gcc 和 make 等工具;
在搜索框里分别搜索gcc和make,必须是
Devel Install 栏的。
3、Cygwin安装目录下,找到home/username的目录下的.bash_profile文件,打开文件在最后加上:
NDK=/cygdrive/d:cygwin/android-ndk-r4-crystax
export NDK
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{
-
-
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);
-
-
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)+"毫秒");
-
}
-
}
-
}
-
-
-
-
-
-
-
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");
-
}
-
-
-
-
-
-
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;
-
}
-
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使用NDK把彩图转换灰度图的方法,在Android项目开发中有一定的实用价值,需要的朋友可以参考下
不管你是想将已经存在的原生代码应用移植到Android平台上还是准备开始在Android平台上进行软件开发,使用《Android C++高级编程——使用NDK》一书提供的技术可以构建更出色的应用。本书将展示构建性能更好的复杂原生...
《Android C++高级编程——使用NDK》提供了Java原生接口(JNI)的概述、Bionic API、POSIX 线程和套接字、C++支持、原生图形和声音API以及NEON/SIMD优化,在一个游戏应用案例的帮助下,你将学到很多关键技能。...
Android允许应用开发者通过Android原生开发包(NDK)使用诸如C和C++之类的原生代码语言实现他们的部分应用。《移动开发经典丛书·Android C++高级编程:使用NDK》中我们将学习如何用AndroidNDK通过原生代码语言去...
Android允许应用开发者通过Android原生开发包(NDK)使用诸如C和C++之类的原生代码语言实现他们的部分应用。《移动开发经典丛书·Android C++高级编程:使用NDK》中我们将学习如何用AndroidNDK通过原生代码语言去...
Android C++高级编程 使用NDK,Android C++高级编程 使用NDK
Android C++高级编程:使用NDK(完整版带书签),目前来说最好的了
ndk-Android C++高级编程:使用NDK_Onur Cinar,于红.zipndk-Android C++高级编程:使用NDK_Onur Cinar,于红.zipndk-Android C++高级编程:使用NDK_Onur Cinar,于红.zipndk-Android C++高级编程:使用NDK_Onur Cinar,...
Android C++高级编程:使用NDK
Android C++高级编程:使用NDK_中文,高清带目录,高级进阶必备书籍
Android C++高级编程使用NDK [ Pro Android C++ with the NDK ]书源码
使用Android NDK编译Android平台的eXosip库,有静态库和动态库。
第2章 深入了解androidndk 35 第3章 用jni实现与原生代码通信 57 第4章 使用swig自动生成jni代码 81 第5章 日志、调试及故障处理 111 第6章 bionic api入门 135 第7章 原生线程 155 第8章 posix socket api:面向...
android-ndk(android-ndk-r26b-windows.zip)适用于Windows系统
android-ndk(android-ndk-r25b-darwin.zip)适用于macOS系统
android-ndk(android-ndk-r25b-windows.zip)适用于Windows系统
android-ndk(android-ndk-r25b-linux.zip)适用于Linux系统
关于如何使用android ndk在c中实现图像过滤器的android项目。
android-ndk-r16b, Android studio jni开发用ndk 包. 文件为网盘地址及密码