Android中播放GIF图片动画


1. 引言

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

2. 功能实现

    (1) 主Activity实现:  

  1. package com.focus.fishme;   
  2. import android.app.Activity;   
  3. import android.os.Bundle;   
  4. public class GIFPlayerActivity extends Activity {   
  5.        
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState) {   
  8.         super.onCreate(savedInstanceState);   
  9.            
  10.         GameView gameView = new GameView(this);   
  11.            
  12.         setContentView(gameView);   
  13.     }   
  14.        
  15. }  

    (2) GIF图片动画View:  

  1. package com.focus.fishme;   
  2. import java.io.ByteArrayOutputStream;   
  3. import java.io.IOException;   
  4. import java.io.InputStream;   
  5. import android.content.Context;   
  6. import android.graphics.Bitmap;   
  7. import android.graphics.Canvas;   
  8. import android.graphics.Paint;   
  9. import android.view.View;   
  10. public class GameView extends View implements Runnable {   
  11.     private GIFFrameManager mGIFFrameManager = null;   
  12.     private Paint mPaint = null;   
  13.     public GameView(Context context) {   
  14.         super(context);   
  15.         mGIFFrameManager = GIFFrameManager.CreateGifImage(this.fileConnect(this  
  16.                 .getResources().openRawResource(R.drawable.cat)));   
  17.         new Thread(this).start();   
  18.     }   
  19.     protected void onDraw(Canvas canvas) {   
  20.         super.onDraw(canvas);   
  21.         mPaint = new Paint();   
  22.         mGIFFrameManager.nextFrame();   
  23.         Bitmap bitmap = mGIFFrameManager.getImage();   
  24.         if (bitmap != null) {   
  25.             canvas.drawBitmap(bitmap, 00, mPaint);   
  26.         }   
  27.     }   
  28.     public byte[] fileConnect(InputStream in) {   
  29.         ByteArrayOutputStream out = new ByteArrayOutputStream();   
  30.         int ch = 0;   
  31.         try {   
  32.             while ((ch = in.read()) != -1) {   
  33.                 out.write(ch);   
  34.             }   
  35.             byte[] b = out.toByteArray();   
  36.             out.close();   
  37.             out = null;   
  38.             in.close();   
  39.             in = null;   
  40.             return b;   
  41.         } catch (IOException e) {   
  42.             e.printStackTrace();   
  43.             return null;   
  44.         }   
  45.     }   
  46.     public void run() {   
  47.         while (!Thread.interrupted()) {   
  48.             try {   
  49.                 Thread.sleep(100);   
  50.                 this.postInvalidate();   
  51.             } catch (Exception ex) {   
  52.                 ex.printStackTrace();   
  53.                 Thread.currentThread().interrupt();   
  54.             }   
  55.         }   
  56.     }   
  57. }   

    (3) GIF图片动画播放管理器:  

  1. package com.focus.fishme;   
  2. import java.util.Vector;   
  3. import android.graphics.Bitmap;   
  4. public class GIFFrameManager {   
  5.        
  6.     private Vector<Bitmap> frames;   
  7.     private int index;   
  8.     public GIFFrameManager() {   
  9.         frames = new Vector<Bitmap>(1);   
  10.         index = 0;   
  11.     }   
  12.     public void addImage(Bitmap image) {   
  13.         frames.addElement(image);   
  14.     }   
  15.     public int size() {   
  16.         return frames.size();   
  17.     }   
  18.     public Bitmap getImage() {   
  19.         if (size() == 0) {   
  20.             return null;   
  21.         } else {   
  22.             return (Bitmap) frames.elementAt(index);   
  23.         }   
  24.     }   
  25.     public void nextFrame() {   
  26.         if (index + 1 < size()) {   
  27.             index++;   
  28.         } else {   
  29.             index = 0;   
  30.         }   
  31.     }   
  32.     public static GIFFrameManager CreateGifImage(byte bytes[]) {   
  33.         try {   
  34.             GIFFrameManager GF = new GIFFrameManager();   
  35.             Bitmap image = null;   
  36.             GIFEncoder gifdecoder = new GIFEncoder(bytes);   
  37.             for (; gifdecoder.moreFrames(); gifdecoder.nextFrame()) {   
  38.                 try {   
  39.                     image = gifdecoder.decodeImage();   
  40.                     if (GF != null && image != null) {   
  41.                         GF.addImage(image);   
  42.                     }   
  43.                     continue;   
  44.                 } catch (Exception e) {   
  45.                     e.printStackTrace();   
  46.                 }   
  47.                 break;   
  48.             }   
  49.             gifdecoder.clear();   
  50.             gifdecoder = null;   
  51.             return GF;   
  52.         } catch (Exception e) {   
  53.             e.printStackTrace();   
  54.             return null;   
  55.         }   
  56.     }   
  57. }  

    (4) GIF图片动画编码:  

  1. package com.focus.fishme;   
  2. import android.graphics.Bitmap;   
  3. import android.graphics.Bitmap.Config;   
  4. public class GIFEncoder {   
  5.     private int E0;   
  6.     private int E1[];   
  7.     private int E2;   
  8.     private int E6;   
  9.     private boolean E7;   
  10.     private int E8[];   
  11.     private int width;   
  12.     private int height;   
  13.     private int ED;   
  14.     private boolean EE;   
  15.     private boolean EF;   
  16.     private int F0[];   
  17.     private int F1;   
  18.     private boolean F2;   
  19.     private int F3;   
  20.     private long F4;   
  21.     private int F5;   
  22.     private static final int F6[] = { 8842 };   
  23.     private static final int F8[] = { 0421 };   
  24.     int curFrame;   
  25.     int poolsize;   
  26.     int FA;   
  27.     byte C2[];   
  28.     int FB;   
  29.     int FC;   
  30.     int FD;   
  31.     public GIFEncoder(byte abyte0[]) {   
  32.         E0 = -1;   
  33.         E1 = new int[280];   
  34.         E2 = -1;   
  35.         E6 = 0;   
  36.         E7 = false;   
  37.         E8 = null;   
  38.         width = 0;   
  39.         height = 0;   
  40.         ED = 0;   
  41.         EE = false;   
  42.         EF = false;   
  43.         F0 = null;   
  44.         F1 = 0;   
  45.         F5 = 0;   
  46.         curFrame = 0;   
  47.         C2 = abyte0;   
  48.         poolsize = C2.length;   
  49.         FA = 0;   
  50.     }   
  51.     public boolean moreFrames() {   
  52.         return poolsize - FA >= 16;   
  53.     }   
  54.     public void nextFrame() {   
  55.         curFrame++;   
  56.     }   
  57.     public Bitmap decodeImage() {   
  58.         return decodeImage(curFrame);   
  59.     }   
  60.     public Bitmap decodeImage(int i) {   
  61.         if (i <= E0) {   
  62.             return null;   
  63.         }   
  64.         if (E0 < 0) {   
  65.             if (!E3()) {   
  66.                 return null;   
  67.             }   
  68.             if (!E4()) {   
  69.                 return null;   
  70.             }   
  71.         }   
  72.         do {   
  73.             if (!E9(1)) {   
  74.                 return null;   
  75.             }   
  76.             int j = E1[0];   
  77.             if (j == 59) {   
  78.                 return null;   
  79.             }   
  80.             if (j == 33) {   
  81.                 if (!E7()) {   
  82.                     return null;   
  83.                 }   
  84.             } else if (j == 44) {   
  85.                 if (!E5()) {   
  86.                     return null;   
  87.                 }   
  88.                 Bitmap image = createImage();   
  89.                 E0++;   
  90.                 if (E0 < i) {   
  91.                     image = null;   
  92.                 } else {   
  93.                     return image;   
  94.                 }   
  95.             }   
  96.         } while (true);   
  97.     }   
  98.     public void clear() {   
  99.         C2 = null;   
  100.         E1 = null;   
  101.         E8 = null;   
  102.         F0 = null;   
  103.     }   
  104.     private Bitmap createImage() {   
  105.         int i = width;   
  106.         int j = height;   
  107.         int j1 = 0;   
  108.         int k1 = 0;   
  109.         int ai[] = new int[4096];   
  110.         int ai1[] = new int[4096];   
  111.         int ai2[] = new int[8192];   
  112.         if (!E9(1)) {   
  113.             return null;   
  114.         }   
  115.         int k = E1[0];   
  116.         int[] image = new int[width * height];   
  117.         int ai3[] = E8;   
  118.         if (EE) {   
  119.             ai3 = F0;   
  120.         }   
  121.         if (E2 >= 0) {   
  122.             ai3[E2] = 0xffffff;   
  123.         }   
  124.         int l2 = 1 << k;   
  125.         int j3 = l2 + 1;   
  126.         int k2 = k + 1;   
  127.         int l3 = l2 + 2;   
  128.         int k3 = -1;   
  129.         int j4 = -1;   
  130.         for (int l1 = 0; l1 < l2; l1++) {   
  131.             ai1[l1] = l1;   
  132.         }   
  133.         int j2 = 0;   
  134.         E2();   
  135.         j1 = 0;   
  136.         label0: for (int i2 = 0; i2 < j; i2++) {   
  137.             int i1 = 0;   
  138.             do {   
  139.                 if (i1 >= i) {   
  140.                     break;   
  141.                 }   
  142.                 if (j2 == 0) {   
  143.                     int i4 = E1(k2);   
  144.                     if (i4 < 0) {   
  145.                         return Bitmap.createBitmap(image, width, height,   
  146.                                 Config.RGB_565);   
  147.                     }   
  148.                     if (i4 > l3 || i4 == j3) {   
  149.                         return Bitmap.createBitmap(image, width, height,   
  150.                                 Config.RGB_565);   
  151.                     }   
  152.                     if (i4 == l2) {   
  153.                         k2 = k + 1;   
  154.                         l3 = l2 + 2;   
  155.                         k3 = -1;   
  156.                         continue;   
  157.                     }   
  158.                     if (k3 == -1) {   
  159.                         ai2[j2++] = ai1[i4];   
  160.                         k3 = i4;   
  161.                         j4 = i4;   
  162.                         continue;   
  163.                     }   
  164.                     int i3 = i4;   
  165.                     if (i4 == l3) {   
  166.                         ai2[j2++] = j4;   
  167.                         i4 = k3;   
  168.                     }   
  169.                     for (; i4 > l2; i4 = ai[i4]) {   
  170.                         ai2[j2++] = ai1[i4];   
  171.                     }   
  172.                     j4 = ai1[i4];   
  173.                     if (l3 >= 4096) {   
  174.                         return Bitmap.createBitmap(image, width, height,   
  175.                                 Config.RGB_565);   
  176.                     }   
  177.                     ai2[j2++] = j4;   
  178.                     ai[l3] = k3;   
  179.                     ai1[l3] = j4;   
  180.                     if (++l3 >= 1 << k2 && l3 < 4096) {   
  181.                         k2++;   
  182.                     }   
  183.                     k3 = i3;   
  184.                 }   
  185.                 int l = ai2[--j2];   
  186.                 if (l < 0) {   
  187.                     return Bitmap.createBitmap(image, width, height,   
  188.                             Config.RGB_565);   
  189.                 }   
  190.                 if (i1 == 0) {   
  191.                     FC = 0;   
  192.                     FB = ai3[l];   
  193.                     FD = 0;   
  194.                 } else if (FB != ai3[l]) {   
  195.                     for (int mm = FD; mm <= FD + FC; mm++) {   
  196.                         image[j1 * width + mm] = FB;   
  197.                     }   
  198.                     FC = 0;   
  199.                     FB = ai3[l];   
  200.                     FD = i1;   
  201.                     if (i1 == i - 1) {   
  202.                         image[j1 * width + i1] = ai3[l];   
  203.                     }   
  204.                 } else {   
  205.                     FC++;   
  206.                     if (i1 == i - 1) {   
  207.                         for (int mm = FD; mm <= FD + FC; mm++) {   
  208.                             image[j1 * width + mm] = FB;   
  209.                         }   
  210.                     }   
  211.                 }   
  212.                 i1++;   
  213.             } while (true);   
  214.             if (EF) {   
  215.                 j1 += F6[k1];   
  216.                 do {   
  217.                     if (j1 < j) {   
  218.                         continue label0;   
  219.                     }   
  220.                     if (++k1 > 3) {   
  221.                         return Bitmap.createBitmap(image, width, height,   
  222.                                 Config.RGB_565);   
  223.                     }   
  224.                     j1 = F8[k1];   
  225.                 } while (true);   
  226.             }   
  227.             j1++;   
  228.         }   
  229.         return Bitmap.createBitmap(image, width, height, Config.RGB_565);   
  230.     }   
  231.     private int E1(int i) {   
  232.         while (F5 < i) {   
  233.             if (F2) {   
  234.                 return -1;   
  235.             }   
  236.             if (F1 == 0) {   
  237.                 F1 = E8();   
  238.                 F3 = 0;   
  239.                 if (F1 <= 0) {   
  240.                     F2 = true;   
  241.                     break;   
  242.                 }   
  243.             }   
  244.             F4 += E1[F3] << F5;   
  245.             F3++;   
  246.             F5 += 8;   
  247.             F1--;   
  248.         }   
  249.         int j = (int) F4 & (1 << i) - 1;   
  250.         F4 >>= i;   
  251.         F5 -= i;   
  252.         return j;   
  253.     }   
  254.     private void E2() {   
  255.         F5 = 0;   
  256.         F1 = 0;   
  257.         F4 = 0L;   
  258.         F2 = false;   
  259.         F3 = -1;   
  260.     }   
  261.     private boolean E3() {   
  262.         if (!E9(6)) {   
  263.             return false;   
  264.         }   
  265.         return E1[0] == 71 && E1[1] == 73 && E1[2] == 70 && E1[3] == 56  
  266.                 && (E1[4] == 55 || E1[4] == 57) && E1[5] == 97;   
  267.     }   
  268.     private boolean E4() {   
  269.         if (!E9(7)) {   
  270.             return false;   
  271.         }   
  272.         int i = E1[4];   
  273.         E6 = 2 << (i & 7);   
  274.         E7 = EB(i, 128);   
  275.         E8 = null;   
  276.         return !E7 || E6(E6, true);   
  277.     }   
  278.     private boolean E5() {   
  279.         if (!E9(9)) {   
  280.             return false;   
  281.         }   
  282.         width = EA(E1[4], E1[5]);   
  283.         height = EA(E1[6], E1[7]);   
  284.         int i = E1[8];   
  285.         EE = EB(i, 128);   
  286.         ED = 2 << (i & 7);   
  287.         EF = EB(i, 64);   
  288.         F0 = null;   
  289.         return !EE || E6(ED, false);   
  290.     }   
  291.     private boolean E6(int i, boolean flag) {   
  292.         int ai[] = new int[i];   
  293.         for (int j = 0; j < i; j++) {   
  294.             if (!E9(3)) {   
  295.                 return false;   
  296.             }   
  297.             ai[j] = E1[0] << 16 | E1[1] << 8 | E1[2] | 0xff000000;   
  298.         }   
  299.         if (flag) {   
  300.             E8 = ai;   
  301.         } else {   
  302.             F0 = ai;   
  303.         }   
  304.         return true;   
  305.     }   
  306.     private boolean E7() {   
  307.         if (!E9(1)) {   
  308.             return false;   
  309.         }   
  310.         int i = E1[0];   
  311.         int j = -1;   
  312.         switch (i) {   
  313.         case 249:   
  314.             j = E8();   
  315.             if (j < 0) {   
  316.                 return true;   
  317.             }   
  318.             if ((E1[0] & 1) != 0) {   
  319.                 E2 = E1[3];   
  320.             } else {   
  321.                 E2 = -1;   
  322.             }   
  323.             break;   
  324.         }   
  325.         do {   
  326.             j = E8();   
  327.         } while (j > 0);   
  328.         return true;   
  329.     }   
  330.     private int E8() {   
  331.         if (!E9(1)) {   
  332.             return -1;   
  333.         }   
  334.         int i = E1[0];   
  335.         if (i != 0 && !E9(i)) {   
  336.             return -1;   
  337.         } else {   
  338.             return i;   
  339.         }   
  340.     }   
  341.     private boolean E9(int i) {   
  342.         if (FA + i >= poolsize) {   
  343.             return false;   
  344.         }   
  345.         for (int j = 0; j < i; j++) {   
  346.             int k = C2[FA + j];   
  347.             if (k < 0) {   
  348.                 k += 256;   
  349.             }   
  350.             E1[j] = k;   
  351.         }   
  352.         FA += i;   
  353.         return true;   
  354.     }   
  355.     private static final int EA(int i, int j) {   
  356.         return j << 8 | i;   
  357.     }   
  358.     private static final boolean EB(int i, int j) {   
  359.         return (i & j) == j;   
  360.     }   
  361. }   

相关内容