android gif文件读取

翻译 2013年12月06日 10:08:15

第一步:完成gif文件的分割,分成多个帧

帧动画解析类

public class GifDecoder
{
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 GifDecoder(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;
}
}

//帧动画


public class GifFrame
{
/* 保存gif中所有帧的向量 */
    private Vector frames;
    
    /* 当前播放的帧的索引 */
    private int index;


    public GifFrame() 
    {
    frames = new Vector(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;
        }
    }
    
    /* 创建GifFrame */
    public static GifFrame CreateGifImage(byte abyte0[]) 
    {
        try 
        {
        GifFrame GF = new GifFrame();
        Bitmap image = null;
            GifDecoder gifdecoder = new GifDecoder(abyte0);
            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;
        }
    } 
}

//动画界面

public class GameView extends View implements Runnable
{
Context mContext = null;


/* 声明GifFrame对象 */
GifFrame mGifFrame = null;


public GameView(Context context)
{
super(context);

mContext = context;
/* 解析GIF动画 */
mGifFrame=GifFrame.CreateGifImage(fileConnect(this.getResources().openRawResource(R.drawable.gif1)));
/* 开启线程 */
new Thread(this).start();
}

public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
/* 下一帧 */
mGifFrame.nextFrame();
/* 得到当前帧的图片 */
Bitmap b=mGifFrame.getImage();

/* 绘制当前帧的图片 */
if(b!=null)
canvas.drawBitmap(b,10,10,null);
}


/**
* 线程处理
*/
public void run()
{
while (!Thread.currentThread().isInterrupted())
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
//使用postInvalidate可以直接在线程中更新界面
postInvalidate();
}
}

/* 读取文件 */
public byte[] fileConnect(InputStream is)
{
try
{    
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int ch = 0;
while( (ch = is.read()) != -1) 
{
baos.write(ch);
}      
byte[] datas = baos.toByteArray();
baos.close(); 
baos = null;
is.close();
is = null;
return datas;
}
catch(Exception e)
{
return null;
}
}
}


Android加载GIF图片的两种方式

Android加载GIF图片的两种方式方式一:使用第三开源框架直接在布局文件中加载gif1.在工程的build.gradle中添加如下buildscript { repositorie...
  • xinpengfei521
  • xinpengfei521
  • 2017年05月30日 10:54
  • 6559

Android下载并显示GIF图

最近项目需要实现在线加载GIF图的功能,于是我在网上翻了一番,发现有个开源项目(android-gif-drawable)可以很好的支持GIF动态图的显示。而且它的底层解码使用C实现,极大的提高了解码...
  • u012964281
  • u012964281
  • 2015年04月30日 14:07
  • 2358

制作Android Demo GIF:程序演示效果GIF图录制

在平时写博客或者分享自己写的程序效果的时候经常需要做成GIF图,以下就是介绍几种常用的GIF录制方法: 一、录制工具  1、(生成动画的工具:Ulead GIF Animator),可以讲单独的图片生...
  • zxccxzzxz
  • zxccxzzxz
  • 2016年08月23日 00:08
  • 1076

在Android中显示GIF动画

gif图动画在android中还是比较常用的,比如像新浪微博中,有很多gif图片,而且展示非常好,所以我也想弄一个。经过我多方的搜索资料和整理,终于弄出来了,其实github上有很多开源的gif的展示...
  • loongggdroid
  • loongggdroid
  • 2014年03月13日 13:47
  • 90137

binbinyang---Android实现显示GIF图片

最近.一个朋友跟我说想,我给她弄个闹钟APP软件...功能其实很简单...只需要弄个简单的闹钟.自己设计设计时间.然后时间到了的时候,闹铃放的声音是男朋友录制好的声音...于是就开始整了.... 第一...
  • yangbin0513
  • yangbin0513
  • 2016年11月02日 11:43
  • 2332

【Android Studio】制作清晰Gif截图以作为项目的运行效果

原文地址: http://www.jianshu.com/p/f8e22be832a1
  • wenbitianxiafeng
  • wenbitianxiafeng
  • 2015年09月21日 17:41
  • 1797

Android加载Gif和ImageView的通用解决方案:android-gif-drawable(1)

 Android加载Gif和ImageView的通用解决方案:android-gif-drawable(1) Android自己的ImageView或者View不能直接加载运行Gif图片,如果...
  • zhangphil
  • zhangphil
  • 2016年03月07日 15:55
  • 30467

Android屏幕内容制作成GIF图方式

1.方式 1.1方式一:先把App操作过程录制成视频,然后根据视频转换成Gif 参考:http://www.jb51.net/article/78236.htm 1.2方式二:采用截屏的方式得到...
  • u014686875
  • u014686875
  • 2016年04月11日 20:03
  • 3891

Android根据Url显示gif类型图片

Android根据Url显示gif图片
  • u014620028
  • u014620028
  • 2016年03月25日 17:04
  • 1509

Android开发笔记(十七)GIF动画的实现GifAnimation

GIF在Windows上是常见的图片格式,主要用来播放短小的动画。但在手机上由于系统资源紧张,所以Android并没有直接支持GIF格式,如果在ImageView中放入一张gif文件,你会发现显示出来...
  • aqi00
  • aqi00
  • 2015年12月11日 17:10
  • 2848
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android gif文件读取
举报原因:
原因补充:

(最多只允许输入30个字)