最近闲来无事,折腾了一下关于gif图片在Android上的显示(大家都知道,Android本身不支持gif图片的显示,当然通过Media还是能够实现gif的播放的)。网上找到的实现gif图片展示的主要是两种方式:使用java实现解码,或者使用编辑工具将gif图片拆分为多张图片,并编写xml文件,以帧动画的形式播放,另外还有个牛人,直接修改了Android框架层的源码,让android系统支持gif解码的。
最后,我参考了一个android的开源项目,gifView,实现了一个基于native层的gif解码。
以下是我参考的资料:
解码的算法是直接抄袭了GifView,基本上就是C++语言重新实现了一下,解码重写了一下SurfaceView控件来实现gif的播放。以下贴上部分的核心代码:
Gif.java
- package com.ray.test.gif;
- import java.util.ArrayList;
- public class Gif {
- public class Frame {
- private int delayTime;
- private Bitmap image;
- private boolean userInput = false;
- public Frame(int delay, int[] color) {
- delayTime = delay;
- image = Bitmap.createBitmap(color, mWidth, mHeight, Config.RGB_565);
- }
- private Frame setUserInput() {
- userInput = true;
- return this;
- }
- public int getDelay() {
- return delayTime;
- }
- public Bitmap getImage() {
- return image;
- }
- public boolean isUserInput() {
- return userInput;
- }
- }
- private int mWidth;
- private int mHeight;
- private List<Frame> mFrames = new ArrayList<Frame>();
- public Gif(int width, int height) {
- mWidth = width;
- mHeight = height;
- }
- public int getWidth() {
- return mWidth;
- }
- public int getHeight() {
- return mHeight;
- }
- public void addFrame(int delay, int[] color, boolean userInput) {
- synchronized (mFrames) {
- if (!userInput)
- mFrames.add(new Frame(delay, color));
- else
- mFrames.add(new Frame(delay, color).setUserInput());
- }
- }
- public int getFrameCount() {
- synchronized (mFrames) {
- return mFrames.size();
- }
- }
- public Frame getFrame(int idx) {
- synchronized (mFrames) {
- if (idx < 0 || idx >= mFrames.size())
- return null;
- return mFrames.get(idx);
- }
- }
- }
GifDecoder.java
- package com.ray.test.gif;
- import java.io.File;
- public class GifDecoder {
- private static final String MYTAG = "Ray";
- private static final String CLASS_NAME = "GifDecoder";
- public interface DecodeResult {
- public void onDecodeFinished(int count);
- }
- private static Gif sGif;
- private static DecodeResult sListener;
- private static boolean sIsReady = false;
- static void decode(String filePath, DecodeResult result) throws FileNotFoundException {
- File f = new File(filePath);
- if (f.exists()) {
- sListener = result;
- sIsReady = false;
- sGif = null;
- WorkThread thread = new WorkThread(filePath);
- thread.start();
- } else
- throw new FileNotFoundException("can not find file:" + filePath);
- }
- static Gif getImage() {
- return sGif;
- }
- private static void onDecodeFinished(String count) {
- Log.d(MYTAG, CLASS_NAME + ": onDecodeFinished, count = " + count);
- int c = Integer.parseInt(count);
- getFrames(c);
- if(c == 0)
- mHandler.obtainMessage(c).sendToTarget();
- }
- private static void getFrames(int idx) {
- if(idx == 0)
- sGif = new Gif(getWidth(), getHeight());
- sGif.addFrame(getDelay(idx), getColors(idx), getUserInput(idx));
- }
- private static