Android合成GIF图片JNI版

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

 

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值