1. 引言

在Android中,默认情况下是不允许播放GIF图片动画的,这时需要自己实现来播放GIF动画,在网上搜索了一个可用的实现,贴出来与大家共享。

2. 功能实现

(1) 主Activity实现:package com.focus.fishme; import android.app.Activity; import android.os.Bundle; public class GIFPlayerActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); GameView gameView = new GameView(this); setContentView(gameView); } }

(2) GIF图片动画View:package com.focus.fishme; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.view.View; public class GameView extends View implements Runnable { private GIFFrameManager mGIFFrameManager = null; private Paint mPaint = null; public GameView(Context context) { super(context); mGIFFrameManager = GIFFrameManager.CreateGifImage(this.fileConnect(this .getResources().openRawResource(R.drawable.cat))); new Thread(this).start(); } protected void onDraw(Canvas canvas) { super.onDraw(canvas); mPaint = new Paint(); mGIFFrameManager.nextFrame(); Bitmap bitmap = mGIFFrameManager.getImage(); if (bitmap != null) { canvas.drawBitmap(bitmap, 0, 0, mPaint); } } public byte[] fileConnect(InputStream in) { ByteArrayOutputStream out = new ByteArrayOutputStream(); int ch = 0; try { while ((ch = in.read()) != -1) { out.write(ch); } byte[] b = out.toByteArray(); out.close(); out = null; in.close(); in = null; return b; } catch (IOException e) { e.printStackTrace(); return null; } } public void run() { while (!Thread.interrupted()) { try { Thread.sleep(100); this.postInvalidate(); } catch (Exception ex) { ex.printStackTrace(); Thread.currentThread().interrupt(); } } } }

(3) GIF图片动画播放管理器:package com.focus.fishme; import java.util.Vector; import android.graphics.Bitmap; public class GIFFrameManager { private Vector<Bitmap> frames; private int index; public GIFFrameManager() { frames = new Vector<Bitmap>(1); index = 0; } public void addImage(Bitmap image) { frames.addElement(image); } public int size() { return frames.size(); } public Bitmap getImage() { if (size() == 0) { return null; } else { return (Bitmap) frames.elementAt(index); } } public void nextFrame() { if (index + 1 < size()) { index++; } else { index = 0; } } public static GIFFrameManager CreateGifImage(byte bytes[]) { try { GIFFrameManager GF = new GIFFrameManager(); Bitmap image = null; GIFEncoder gifdecoder = new GIFEncoder(bytes); for (; gifdecoder.moreFrames(); gifdecoder.nextFrame()) { try { image = gifdecoder.decodeImage(); if (GF != null && image != null) { GF.addImage(image); } continue; } catch (Exception e) { e.printStackTrace(); } break; } gifdecoder.clear(); gifdecoder = null; return GF; } catch (Exception e) { e.printStackTrace(); return null; } } }

(4) GIF图片动画编码:package com.focus.fishme; import android.graphics.Bitmap; import android.graphics.Bitmap.Config; public class GIFEncoder { private int E0; private int E1[]; private int E2; private int E6; private boolean E7; private int E8[]; private int width; private int height; private int ED; private boolean EE; private boolean EF; private int F0[]; private int F1; private boolean F2; private int F3; private long F4; private int F5; private static final int F6[] = { 8, 8, 4, 2 }; private static final int F8[] = { 0, 4, 2, 1 }; int curFrame; int poolsize; int FA; byte C2[]; int FB; int FC; int FD; public GIFEncoder(byte abyte0[]) { E0 = -1; E1 = new int[280]; E2 = -1; E6 = 0; E7 = false; E8 = null; width = 0; height = 0; ED = 0; EE = false; EF = false; F0 = null; F1 = 0; F5 = 0; curFrame = 0; C2 = abyte0; poolsize = C2.length; FA = 0; } public boolean moreFrames() { return poolsize - FA >= 16; } public void nextFrame() { curFrame++; } public Bitmap decodeImage() { return decodeImage(curFrame); } public Bitmap decodeImage(int i) { if (i <= E0) { return null; } if (E0 < 0) { if (!E3()) { return null; } if (!E4()) { return null; } } do { if (!E9(1)) { return null; } int j = E1[0]; if (j == 59) { return null; } if (j == 33) { if (!E7()) { return null; } } else if (j == 44) { if (!E5()) { return null; } Bitmap image = createImage(); E0++; if (E0 < i) { image = null; } else { return image; } } } while (true); } public void clear() { C2 = null; E1 = null; E8 = null; F0 = null; } private Bitmap createImage() { int i = width; int j = height; int j1 = 0; int k1 = 0; int ai[] = new int[4096]; int ai1[] = new int[4096]; int ai2[] = new int[8192]; if (!E9(1)) { return null; } int k = E1[0]; int[] image = new int[width * height]; int ai3[] = E8; if (EE) { ai3 = F0; } if (E2 >= 0) { ai3[E2] = 0xffffff; } int l2 = 1 << k; int j3 = l2 + 1; int k2 = k + 1; int l3 = l2 + 2; int k3 = -1; int j4 = -1; for (int l1 = 0; l1 < l2; l1++) { ai1[l1] = l1; } int j2 = 0; E2(); j1 = 0; label0: for (int i2 = 0; i2 < j; i2++) { int i1 = 0; do { if (i1 >= i) { break; } if (j2 == 0) { int i4 = E1(k2); if (i4 < 0) { return Bitmap.createBitmap(image, width, height, Config.RGB_565); } if (i4 > l3 || i4 == j3) { return Bitmap.createBitmap(image, width, height, Config.RGB_565); } if (i4 == l2) { k2 = k + 1; l3 = l2 + 2; k3 = -1; continue; } if (k3 == -1) { ai2[j2++] = ai1[i4]; k3 = i4; j4 = i4; continue; } int i3 = i4; if (i4 == l3) { ai2[j2++] = j4; i4 = k3; } for (; i4 > l2; i4 = ai[i4]) { ai2[j2++] = ai1[i4]; } j4 = ai1[i4]; if (l3 >= 4096) { return Bitmap.createBitmap(image, width, height, Config.RGB_565); } ai2[j2++] = j4; ai[l3] = k3; ai1[l3] = j4; if (++l3 >= 1 << k2 && l3 < 4096) { k2++; } k3 = i3; } int l = ai2[--j2]; if (l < 0) { return Bitmap.createBitmap(image, width, height, Config.RGB_565); } if (i1 == 0) { FC = 0; FB = ai3[l]; FD = 0; } else if (FB != ai3[l]) { for (int mm = FD; mm <= FD + FC; mm++) { image[j1 * width + mm] = FB; } FC = 0; FB = ai3[l]; FD = i1; if (i1 == i - 1) { image[j1 * width + i1] = ai3[l]; } } else { FC++; if (i1 == i - 1) { for (int mm = FD; mm <= FD + FC; mm++) { image[j1 * width + mm] = FB; } } } i1++; } while (true); if (EF) { j1 += F6[k1]; do { if (j1 < j) { continue label0; } if (++k1 > 3) { return Bitmap.createBitmap(image, width, height, Config.RGB_565); } j1 = F8[k1]; } while (true); } j1++; } return Bitmap.createBitmap(image, width, height, Config.RGB_565); } private int E1(int i) { while (F5 < i) { if (F2) { return -1; } if (F1 == 0) { F1 = E8(); F3 = 0; if (F1 <= 0) { F2 = true; break; } } F4 += E1[F3] << F5; F3++; F5 += 8; F1--; } int j = (int) F4 & (1 << i) - 1; F4 >>= i; F5 -= i; return j; } private void E2() { F5 = 0; F1 = 0; F4 = 0L; F2 = false; F3 = -1; } private boolean E3() { if (!E9(6)) { return false; } return E1[0] == 71 && E1[1] == 73 && E1[2] == 70 && E1[3] == 56 && (E1[4] == 55 || E1[4] == 57) && E1[5] == 97; } private boolean E4() { if (!E9(7)) { return false; } int i = E1[4]; E6 = 2 << (i & 7); E7 = EB(i, 128); E8 = null; return !E7 || E6(E6, true); } private boolean E5() { if (!E9(9)) { return false; } width = EA(E1[4], E1[5]); height = EA(E1[6], E1[7]); int i = E1[8]; EE = EB(i, 128); ED = 2 << (i & 7); EF = EB(i, 64); F0 = null; return !EE || E6(ED, false); } private boolean E6(int i, boolean flag) { int ai[] = new int[i]; for (int j = 0; j < i; j++) { if (!E9(3)) { return false; } ai[j] = E1[0] << 16 | E1[1] << 8 | E1[2] | 0xff000000; } if (flag) { E8 = ai; } else { F0 = ai; } return true; } private boolean E7() { if (!E9(1)) { return false; } int i = E1[0]; int j = -1; switch (i) { case 249: j = E8(); if (j < 0) { return true; } if ((E1[0] & 1) != 0) { E2 = E1[3]; } else { E2 = -1; } break; } do { j = E8(); } while (j > 0); return true; } private int E8() { if (!E9(1)) { return -1; } int i = E1[0]; if (i != 0 && !E9(i)) { return -1; } else { return i; } } private boolean E9(int i) { if (FA + i >= poolsize) { return false; } for (int j = 0; j < i; j++) { int k = C2[FA + j]; if (k < 0) { k += 256; } E1[j] = k; } FA += i; return true; } private static final int EA(int i, int j) { return j << 8 | i; } private static final boolean EB(int i, int j) { return (i & j) == j; } }

注:需要整体工程的请留邮箱。

更多相关文章

  1. 2010.12.15——— android listView 显示图片
  2. Android拍照、相册选取、裁剪图片综合Demo
  3. Android 图片对比(图片相似度)代码
  4. 麦子学院android开发笔记:Android更换RatingBar图片
  5. Android UI开发第十九篇――介绍一个开源的gifview――Android显
  6. Android Activity与Activity切换动画

随机推荐

  1. Golang如何打包在Linux上部署
  2. golang开发工程师是做什么的
  3. golang如何创建目录
  4. golang的优势在哪里
  5. golang可以写web吗?
  6. golang结构体怎么判断是否为空
  7. golang判断map是否存在key
  8. 2021年放弃Python选择Go的原因
  9. golang接口可以嵌套吗
  10. 运行golang程序提示进程无法启动