android之Gif处理(解决OOM问题)

Android开源项目:GifView——Android显示GIF动画

作者:ant.cy.liao

主页:http://code.google.com/p/gifview/

下载:http://code.google.com/p/gifview/downloads/list

简介:android中现在没有直接显示gif的view,只能通过mediaplay来显示,且还常常不能正常显示出来,为此写了这个gifview,其用法和imageview一样

 

使用方法:

1-把GifView.jar加入你的项目。

2-在xml中配置GifView的基本属性,GifView继承自View类,和Button、ImageView一样是一个UI控件。如:

 <com.ant.liao.GifView android:id="@+id/gif2"

       android:layout_height="wrap_content"android:layout_width="wrap_content"

       android:paddingTop="4px" android:paddingLeft="14px"android:enabled="false" />

 

3-在代码中配置常用属性:

   // 从xml中得到GifView的句柄

       gf1 = (GifView) findViewById(R.id.gif1);

       // 设置Gif图片源

       gf1.setGifImage(R.drawable.gif1);

       // 添加监听器

       gf1.setOnClickListener(this);

       // 设置显示的大小,拉伸或者压缩

       gf1.setShowDimension(300, 300);

       // 设置加载方式:先加载后显示、边加载边显示、只显示第一帧再显示

       gf1.setGifImageType(GifImageType.COVER);

 

GifView的Jar包共有四个类:

GifAction.java:

观察者类,监视GIF是否加载成功

package com.ant.liao;

public interface GifAction {

/**

 *gif解码观察者

  *@hide

  *@param parseStatus 解码是否成功,成功会为true         

  *@param frameIndex 当前解码的第几帧,当全部解码成功后,这里为-1         

 */       

  public void parseOk(boolean parseStatus,int frameIndex);

}

 

GifFrame.java

里面三个成员:当前图片、延时、下张Frame的链接。

package com.ant.liao;

import android.graphics.Bitmap;

public class GifFrame {

/**

* 构造函数

* @param im 图片

* @param del 延时

*/       

public GifFrame(Bitmap im, int del){ 

image = im;        

delay = del;    

}          

public GifFrame(String name,intdel){  

imageName = name;        

delay = del;       

}              

/**图片*/     

public Bitmap image;  

/**延时*/       

public int delay; 

/**当图片存成文件时的文件名*/

public String imageName = null;     

/**下一帧*/     

public GifFrame nextFrame = null;

}

 

GifDecoder.java

解码线程类

http://code.google.com/p/gifview/source/browse/trunk/src/com/ant/liao/GifDecoder.java

 

GifView.java

主类,包括常用方法,如GifView构造方法、设置图片源、延迟、绘制等。

http://code.google.com/p/gifview/source/browse/trunk/src/com/ant/liao/GifView.java

 

 

 

Android开源项目:android-gif-drawable——Android显示GIF动画

android-gif-drawable

Views andDrawable for animated GIFs in Android.

项目地址:https://github.com/koral--/android-gif-drawable

Overview

Bundled GIFLibvia JNI is used to render frames. This way should be more efficient thanWebView or Movie classes.
Animation starts automatically and run only if View with attached GifDrawableis visible.

Download

Latest release downloads

Setup

Gradle(Android Studio)

Insert thefollowing dependency to build.gradle file of your project.

dependencies {

   compile 'pl.droidsonroids.gif:android-gif-drawable:1.0.+'

}

 

Note thatMaven central repository should be defined eg. in top-level build.gradle likethis:

buildscript {

   repositories {

       mavenCentral()

   }

}

allprojects {

   repositories {

       mavenCentral()

   }

}

 

Mavendependency

SDK with APIlevel 19 is needed. If you don't have it in your local repository, downloadmaven-android-sdk-deployer and installSDK level 19: mvn install -P 4.4 (from maven-android-sdk-deployer directory).Then add dependency in pom.xml of your project:

<dependency>

   <groupId>pl.droidsonroids.gif</groupId>

   <artifactId>android-gif-drawable</artifactId>

   <version>insert latest version here</version>

    <type>aar</type>

</dependency>

 

Requirements

·        Android 1.6+ (API level 4+)

Building fromsource

·        Android NDKneeded tocompile native sources

Usage

From XML

The simplestway is to use GifImageView (or GifImageButton) like a normal ImageView:

<pl.droidsonroids.gif.GifImageView

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   android:src="@drawable/src_anim"

   android:background="@drawable/bg_anim"

   />

 

If drawablesdeclared by android:src and/or android:background are GIF files then they willbe automatically recognized as GifDrawables and animated. If given drawable isnot a GIF then mentioned Views work like plain ImageView and ImageButton.

GifTextViewallows you to use GIFs as compound drawables and background.

<pl.droidsonroids.gif.GifTextView

   android:layout_width="match_parent"

   android:layout_height="match_parent"

   android:drawableTop="@drawable/left_anim"

   android:drawableStart="@drawable/left_anim"

   android:background="@drawable/bg_anim"

   />

 

From Java code

GifImageView,GifImageButton and GifTextView have also hooks for setters implemented. Soanimated GIFs can be set by calling setImageResource(int resId) andsetBackgroundResource(int resId)

GifDrawablecan be constructed directly from various sources:

       //asset file

       GifDrawable gifFromAssets = new GifDrawable( getAssets(),"anim.gif" );

 

       //resource (drawable or raw)

       GifDrawable gifFromResource = new GifDrawable( getResources(),R.drawable.anim );

 

       //byte array

       byte[] rawGifBytes = ...

       GifDrawable gifFromBytes = new GifDrawable( rawGifBytes );

 

       //FileDescriptor

       FileDescriptor fd = new RandomAccessFile( "/path/anim.gif","r" ).getFD();

       GifDrawable gifFromFd = new GifDrawable( fd );

 

       //file path

       GifDrawable gifFromPath = new GifDrawable( "/path/anim.gif" );

 

       //file

       File gifFile = new File(getFilesDir(),"anim.gif");

       GifDrawable gifFromFile = new GifDrawable(gifFile);

 

       //AssetFileDescriptor

       AssetFileDescriptor afd = getAssets().openFd( "anim.gif" );

       GifDrawable gifFromAfd = new GifDrawable( afd );

 

       //InputStream (it must support marking)

       InputStream sourceIs = ...

       BufferedInputStream bis = new BufferedInputStream( sourceIs, GIF_LENGTH);

       GifDrawable gifFromStream = new GifDrawable( bis );

 

       //direct ByteBuffer

       ByteBuffer rawGifBytes = ...

       GifDrawable gifFromBytes = new GifDrawable( rawGifBytes );

 

 

InputStreamsare closed automatically in finalizer if GifDrawable is no longer needed so youdon't need to explicitly close them. Calling recycle() will also closeunderlaying input source.

Note that allinput sources need to have ability to rewind to the begining. It is required tocorrectly play animated GIFs (where animation is repeatable) since subsequentframes are decoded on demand from source.

Animationcontrol

GifDrawableimplements an Animatable and MediaPlayerControl so you can use its methods andmore:

·        stop()- stops the animation, can becalled from any thread

·        start()- starts the animation, canbe called from any thread

·        isRunning()- returns whetheranimation is currently running or not

·        reset()- rewinds the animation, doesnot restart stopped one

·        setSpeed(float factor)- sets newanimation speed factor, eg. passing 2.0f will double the animation speed

·        seekTo(int position)- seeksanimation (within current loop) to given position (in milliseconds)Only seeking forward is supported

·        getDuration()- returns duration ofone loop of the animation

·        getCurrentPosition()- returnselapsed time from the beginning of a current loop of animation

UsingMediaPlayerControl

Standardcontrols for a MediaPlayer (like in VideoView) can be used to control GIFanimation and show its current progress.

Just setGifDrawable as MediaPlayer on your MediaController like this:

   @Override

   protected void onCreate ( Bundle savedInstanceState )

   {

       super.onCreate( savedInstanceState );

       GifImageButton gib = new GifImageButton( this );

       setContentView( gib );

       gib.setImageResource( R.drawable.sample );

       final MediaController mc = new MediaController( this );

       mc.setMediaPlayer( ( GifDrawable ) gib.getDrawable() );

       mc.setAnchorView( gib );

       gib.setOnClickListener( new OnClickListener()

       {

            @Override

            public void onClick ( View v )

           {

                mc.show();

            }

       } );

   }

 

Retrieving GIFmetadata

·        getLoopCount()- returns a loop countas defined in NETSCAPE 2.0 extension

·        getNumberOfFrames()- returns numberof frames (at least 1)

·        getComment()- returns comment text(null if GIF has no comment)

·        getFrameByteCount()- returns minimumnumber of bytes that can be used to store pixels of the single frame

·        getAllocationByteCount()- returnssize (in bytes) of the allocated memory used to store pixels of givenGifDrawable

·        getInputSourceByteCount()- returnslength (in bytes) of the backing input data

·        toString()- returns human readableinformation about image size and number of frames (intended for debuggingpurpose)

Advanced

·        recycle()- provided to speed upfreeing memory (like in android.graphics.Bitmap).

·        getError()- returns last errordetails

References

This libraryuses code from GIFLIB5.0.5 andSKIA.

License

MIT License
See LICENSE file.

 

PS

GifView:已知bug: 如果图档过大,会出现OOM

 if the gif image is too large,maybe OOM.

              为了解决图档太大时的OOM,我想把gif解析时的图片先存入到文件中,在显示时直接从文件中读入,但这样的话,显示的效果不好。

            而android-gif-drawable并没有此问题,底层解码使用C实现,极大的提高了解码效率,同时很大程度上避免了OOM现象出现。


这是我做的一个小demo

https://github.com/changkongyx/gifDemo


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值