http://www.johdan.com/android_gif_merge.html
一、NDK环境的搭建与Eclipse配置NDK_R7开发环境
这里主要是大家查下网上的资料即可,我参考的是:
http://blog.csdn.net/chaseli1984/article/details/7166542
二、下载合成GIF的C++相关源码文件
http://jiggawatt.org/badc0de/android/index.html#gifflen
三、使用gifflen
1、在你的项目中根目录建立jni文件夹
2、将下载好解压缩后的文件放入jni文件夹下
3、修正对应的方法名。
NDK里面书写方法的名称需同你native 类的包名相同,举个例子我的native方法类的完整路径是:com.johdan.gif.merge.util.GifUtil.java那么我需要将下载回来的源码里面的jni call的方法名称改为以Java_com_johdan_gif_merge_util_GifUtil开头即可。
4、编译你的JNI,用cygwin进入该项目的jni目录下,或者使用配置eclipse的NDK builder 也可以。
我这里用的是eclipse编译JNI。
四、编译通过后,大功告成,直接使用吧!
这里我准备了一个Demo,想尝试的同学可以看看下载安装看看演示效果。
核心代码:
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
|
package
com.johdan.gif.merge;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileNotFoundException;
import
com.johdan.gif.merge.util.GifUtil;
import
android.app.Activity;
import
android.app.ProgressDialog;
import
android.graphics.Bitmap;
import
android.graphics.BitmapFactory;
import
android.os.Bundle;
import
android.os.Environment;
import
android.os.Handler;
import
android.os.Message;
import
android.widget.Toast;
/**
* MainActivity
* @author www.jodhan.com
*
*/
public
class
MainActivity
extends
Activity {
Boolean isSuccess =
false
;
ProgressDialog progressDialog;
private
Handler mHandler =
new
Handler() {
@Override
public
void
handleMessage(Message msg) {
switch
(msg.what){
case
1
:
if
(progressDialog !=
null
){
progressDialog.dismiss();
}
Toast.makeText(getApplicationContext(),
"图片合成成功,请查看SD卡test.gif!"
,
2000
).show();
break
;
case
2
:
getGif();
break
;
}
}
};
/** Called when the activity is first created. */
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
progressDialog=
new
ProgressDialog(
this
);
progressDialog.setMessage(
"图片合成中,请稍等。"
);
progressDialog.show();
getGif();
}
public
void
getGif() {
new
Thread(){
@Override
public
void
run() {
// TODO Auto-generated method stub
String filepath=Environment.getExternalStorageDirectory() +
"/test.gif"
;
isSuccess = convertBitmapToGIF(filepath);
Message msg=
new
Message();
if
(isSuccess){
msg.what =
1
;
mHandler.sendMessage(msg);
isSuccess=
false
;
}
else
{
msg.what =
2
;
mHandler.sendMessage(msg);
}
super
.run();
}
}.start();
}
/**
* 合成gif
* @param filepath 保存的路径
* @return
*/
public
boolean
convertBitmapToGIF(String filepath){
Boolean isSuccess=
false
;
Bitmap[] bitmaps = getBitmaps();
int
delay =
100
;
new
GifUtil().Encode(filepath, bitmaps, delay);
File f=
new
File(filepath);
if
(f.exists()){
isSuccess=
true
;
}
return
isSuccess;
}
/**
* 产生多个bitmap
* @return
*/
public
Bitmap[] getBitmaps(){
Bitmap[] bitmaps =
new
Bitmap[
3
];
String sdPath=Environment.getExternalStorageDirectory() +
""
;
File file1 =
new
File(sdPath+
"/1.jpg"
);
File file2 =
new
File(sdPath+
"/2.jpg"
);
File file3 =
new
File(sdPath+
"/3.jpg"
);
Bitmap bitmap1 = decodeFile(file1);
Bitmap bitmap2 = decodeFile(file2);
Bitmap bitmap3 = decodeFile(file3);
bitmaps[
0
]=bitmap1;
bitmaps[
1
]=bitmap2;
bitmaps[
2
]=bitmap3;
return
bitmaps;
}
/**
* 将对应的文件转换为bitmap
* decodes image and scales it to reduce memory consumption
* @param f
* @return
*/
private
Bitmap decodeFile(File f) {
try
{
// decode image size
BitmapFactory.Options o =
new
BitmapFactory.Options();
o.inJustDecodeBounds =
true
;
BitmapFactory.decodeStream(
new
FileInputStream(f),
null
, o);
// Find the correct scale value. It should be the power of 2.
final
int
REQUIRED_SIZE =
70
;
int
width_tmp = o.outWidth, height_tmp = o.outHeight;
int
scale =
1
;
while
(
true
) {
if
(width_tmp /
2
< REQUIRED_SIZE
|| height_tmp /
2
< REQUIRED_SIZE)
break
;
width_tmp /=
2
;
height_tmp /=
2
;
scale *=
2
;
}
// decode with inSampleSize
BitmapFactory.Options o2 =
new
BitmapFactory.Options();
o2.inSampleSize = scale;
return
BitmapFactory.decodeStream(
new
FileInputStream(f),
null
, o2);
}
catch
(FileNotFoundException e) {
}
return
null
;
}
}
|
1
|
|
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
90
91
92
93
94
95
|
package
com.johdan.gif.merge.util;
import
android.graphics.Bitmap;
import
android.util.Log;
/**
* 需要new 出本类,然后调用Encode方法即可
* @param fileName 文件保存路径
* @param bitmaps bitmap的集合
* @param delay 每帧间隔的秒
* @author www.johdan.com
*
*/
public
class
GifUtil {
// private static final String PATH = "/data/data/com.bingzer.android.stickdraw/lib/libgifflen.so";
// private boolean hasError = false;
//
// public GifUtil(){
// try{
// System.load("/data/data/com.bingzer.android.stickdraw/lib/libgifflen.so");
// return;
// }
// catch (Throwable localThrowable){
// Log.e("Giffle", "not found: /data/data/cn.qtt.giffle/lib/libgifflen.so");
// this.hasError = true;
// }
// }
// public boolean hasError(){
// return this.hasError;
// }
private
final
String TAG=
this
.getClass().getName();
static
{
System.loadLibrary(
"gifflen"
);
}
/**
* Init the gif file
* @param gifName name
* @param w width
* @param h height
* @param numColors colors
* @param quality
* @param frameDelay times
* @return
*/
public
native
int
Init(String gifName,
int
w,
int
h,
int
numColors,
int
quality,
int
frameDelay);
/*
* close
*
*/
public native void Close();
public native int AddFrame(int[] pixels);
/**
* encode the bitmaps to gif
* @param fileName
* @param bitmaps
* @param delay
*/
public
void
Encode(String fileName,Bitmap[] bitmaps,
int
delay)
{
if
(bitmaps==
null
||bitmaps.length==
0
)
{
throw
new
NullPointerException(
"Bitmaps should have content!!!"
);
}
int
width=bitmaps[
0
].getWidth();
int
height=bitmaps[
0
].getHeight();
if
(Init(fileName,width,height,
256
,
100
,delay)!=
0
)
{
Log.e(TAG,
"GifUtil init failed"
);
return
;
}
for
(Bitmap bp:bitmaps)
{
int
pixels[]=
new
int
[width*height];
bp.getPixels(pixels,
0
, width,
0
,
0
, width, height);
AddFrame(pixels);
}
Close();
}
}
|
Demo下载:GifMerge_GIF本地图片合成案例
最后,感谢leepood的文章http://blog.leepood.com/new-to-android/android-gif-maker