Android提高之使用NDK把彩图转换灰度图的方法

2025-05-27 0 26

一般而言在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 等工具;

如图所示:

Android提高之使用NDK把彩图转换灰度图的方法

在搜索框里分别搜索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文件。

接下来看看本文程序运行的效果:

Android提高之使用NDK把彩图转换灰度图的方法

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

main.xml源码如下:

?

1

2

3

4

5

6
<?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">

<button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnjava" android:text="使用java转换灰度图" />

<button android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/btnndk" android:text="使用ndk转换灰度图" />

<imageview android:id="@+id/imageview01" android:layout_width="fill_parent" android:layout_height="fill_parent" />

</linearlayout>

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89
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的源码如下:

?

1

2

3

4

5

6

7

8

9

10

11
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源码:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34
#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的源码:

?

1

2

3

4

5
local_path:= $(call my-dir)

include $(clear_vars)

local_module := imgtogray

local_src_files := imgtogray.cpp

include $(build_shared_library)

感兴趣的读者可以动手调试一下本文所述代码,相信会对大家进行android项目开发有一定的帮助。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 Android提高之使用NDK把彩图转换灰度图的方法 https://www.kuaiidc.com/76519.html

相关文章

发表评论
暂无评论