Movie 类

官方对这个类连一句介绍都没有,并且所有的方法也没有一行注释,可见多么不受重视!


package android.graphics;
直接继承自Object,直接继承自Object的基本上都是工具类。

Android的ImageView无法直接加载Gif图片,鉴于此,Android社区开发者为解决此问题贡献了很多解决方案,其中一种比较简易的做法是通过Android中的Movie类把一个gif图片当作一个原始的资源加载到Movie,然后Movie将其解析为Movie帧进行加载。

Movie其实管理着GIF动画中的多个帧,只需要通过 setTime() 一下就可以让它在draw()的时候绘出相应的那帧图像,通过当前时间与duration之间的换算关系,便可实现GIF动起来的效果。

对于比较小的gif图片使用此方法还是可以的,要是大的话,建议还是把gif图片转换成一帧一帧的png图片,然后通过animation播放。

简单的利用Movie播放GIF图的控件

setContentView(new CustomGifView(this, R.drawable.ic_launcher)); //显示普通图片
setContentView(new CustomGifView(this, R.drawable.gif1)); //显示gif动图
/**
* 自定义可以循环播放gif动画的View,可以像使用其他控件一样使用
* @author 白乾涛
*/
public class CustomGifView extends View {
private Movie mMovie;
private long mMovieStart;
private int resId;

public CustomGifView(Context context, int resId) {
super(context);
this.resId = resId;
setLayerType(View.LAYER_TYPE_SOFTWARE, null);//必须关闭硬件加速
mMovie = Movie.decodeStream(getResources().openRawResource(resId));//创建Movie对象
}

public void onDraw(Canvas canvas) {
long now = SystemClock.uptimeMillis();//系统当前时刻
//第一次播放
if (mMovieStart == 0) mMovieStart = now;//动画开始的时间
if (mMovie != null) {
int dur = mMovie.duration();//动画持续的时间,也就是完成一次动画的时间
if (dur == 0) dur = 1000;
int relTime = (int) ((now - mMovieStart) % dur);//注意这是取余操作,这才能算出当前这次重复播放的第一帧的时间
mMovie.setTime(relTime);//设置相对本次播放第一帧时间,根据这个时间来决定显示第几帧
mMovie.draw(canvas, 0, 0);
invalidate();
} else {//如果指定的资源不是gif图片,也就是说是普通的图片,则需要手动绘制此图片
canvas.drawBitmap(BitmapFactory.decodeResource(getResources(), resId), getMatrix(), new Paint());
}
}
}

Movie 类的 API

  • static Movie decodeByteArray(byte[] data, int offset, int length)
  • static Movie decodeFile(String pathName)
  • static Movie decodeStream(InputStream is)
  • void draw(Canvas canvas, float x, float y, Paint paint)
  • void draw(Canvas canvas, float x, float y)
  • int duration()
  • int height()
  • boolean isOpaque()
  • boolean setTime(int relativeMilliseconds)
  • int width()

开源库 android-gif-drawable

底层解码使用C实现,极大的提高了解码效率,同时很大程度上避免了OOM。

Views and Drawable for displaying animated GIFs on Android
Bundled GIFLib via JNI is used to render frames. This way should be more efficient than WebView or Movie classes.

Requirements
  • Android 2.3+ (API level 9+)
  • for GifTextureView Android 4.0+ (API level 14+) and hardware-accelerated rendering渲染
  • for GifTexImage2D OpenGL ES 2.0+
Building from source
  • Android NDK needed to compile native sources

配置build.gradle

Insert the following dependency to build.gradle file of your project.
  1. dependencies {
  2.     compile 'pl.droidsonroids.gif:android-gif-drawable:1.2.6'
  3. }

Note that Maven central repository should be defined eg. in top-level build.gradle like this:

  1. buildscript {
  2.     repositories {
  3.         mavenCentral()
  4.     }
  5. }
  6. allprojects {
  7.     repositories {
  8.         mavenCentral()
  9.     }
  10. }

XML中使用

The simplest way 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:background="@drawable/gif1"
android:src="@drawable/gif2"/>
If drawables declared by android:src and/or android:background are GIF files then they will be automatically recognized as GifDrawables and animated. If given drawable is not a GIF then mentioned Views work like plain平常的 ImageView and ImageButton.

GifTextView allows you to use GIFs as compound复合的 drawables and background.
<pl.droidsonroids.gif.GifTextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/gif1"
android:drawableTop="@drawable/gif2"/>

代码中构造GifDrawable

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

GifDrawable can be constructed directly from various sources:
void constructGifDrawable() throws IOException {
//asset file
GifDrawable gifFromAssets = new GifDrawable(getAssets(), "gif1.gif");

//resource (drawable or raw)
GifDrawable gifFromResource = new GifDrawable(getResources(), R.drawable.gif1);

//Uri
ContentResolver contentResolver = null; //can be null for file:// Uris
GifDrawable gifFromUri = new GifDrawable(contentResolver, null);//gifUri

//byte array
byte[] rawGifBytes = null;
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(), "gif1.gif");
GifDrawable gifFromFile = new GifDrawable(gifFile);

//AssetFileDescriptor
AssetFileDescriptor afd = getAssets().openFd("gif1.gif");
GifDrawable gifFromAfd = new GifDrawable(afd);

//InputStream (it must support marking)
InputStream sourceIs = null;
BufferedInputStream bis = new BufferedInputStream(sourceIs, 1024);//GIF_LENGTH
GifDrawable gifFromStream = new GifDrawable(bis);

//direct ByteBuffer
ByteBuffer rawGifByteBuffer = null;
GifDrawable gifFromByteBuffer = new GifDrawable(rawGifByteBuffer);
}

InputStreams are closed automatically in finalizer if GifDrawable is no longer needed so you don't need to explicitly明确的 close them. Calling recycle() will also close underlying潜在的 input source.

Note that all input sources need to have ability to rewind倒回 to the beginning. It is required to correctly play animated GIFs (where animation is repeatable) since subsequent随后的 frames are decoded on demand from source.

动画过程控制 Animation control

GifDrawable implements an Animatable and MediaPlayerControl so you can use its methods and more:
  • stop() - stops the animation, can be called from any thread
  • start() - starts the animation, can be called from any thread
  • isRunning() - returns whether animation is currently running or not
  • reset() - rewinds the animation, does not restart stopped one
  • setSpeed(float factor) - sets new animation speed factor, eg. passing 2.0f will double the animation speed
  • seekTo(int position) - seeks animation (within current loop) to given position (in milliseconds)
  • getDuration() - returns duration of one loop of the animation
  • getCurrentPosition() - returns elapsed time from the beginning of a current loop of animation

使用 MediaPlayerControl

Standard controls for a MediaPlayer (like in VideoView) can be used to control GIF animation and show its current progress.
Just set GifDrawable as MediaPlayer on your MediaController like this:
@BindView(R.id.gif) GifImageView gifView;
android.widget.MediaController mc;
mc = new MediaController(this);
mc.setMediaPlayer((pl.droidsonroids.gif.GifDrawable) gifView.getDrawable());
mc.setAnchorView(gifView);
mc.show();

获取GIF元数据

Retrieving GIF metadata
  • getLoopCount() - returns a loop count as defined in NETSCAPE 2.0 extension
  • getNumberOfFrames() - returns number of frames (at least 1)
  • getComment() - returns comment text (null if GIF has no comment)
  • getFrameByteCount() - returns minimum number of bytes that can be used to store pixels of the single frame
  • getAllocationByteCount() - returns size (in bytes) of the allocated memory used to store pixels of given GifDrawable
  • getInputSourceByteCount() - returns length (in bytes) of the backing input data
  • toString() - returns human readable information about image size and number of frames (intended for debugging purpose)

一个GifDrawable用在多个View上

Associating single GifDrawable instance with multiple Views:
Normally single GifDrawable instance associated with multiple Views will animate only on the last one. To solve that create MultiCallback instance, add Views to it and set callback for given drawable, eg.:
MultiCallback multiCallback = new MultiCallback();
imageView.setImageDrawable(gifDrawable);
multiCallback.addView(imageView);
anotherImageView.setImageDrawable(gifDrawable);
multiCallback.addView(anotherImageView);

gifDrawable.setCallback(multiCallback);

高级API

Advanced
recycle() - provided to speed up freeing memory (like in android.graphics.Bitmap)
isRecycled() - checks whether drawable is recycled
getError() - returns last error details

开源库 Cutta/GifView

Library for playing gifs on Android

Simple android view to display gifs efficiently高效的. You can start, pause and stop gifView.

Inspired by灵感来自 sbakhtiarov/gif-movie-view


这个自定义的View其实主要还是使用了 android.graphics.Movie 这个类。
去看源码时,发现就一个独杆司令GifView,API也就下面几个:

AS中使用

Add these lines on top-level build file
  1. // Top-level build file where you can add configuration options common to all sub-projects/modules.
  2. repositories {
  3.     maven {
  4.         url "https://jitpack.io"
  5.     }
  6. }

On app's build.gradle

  1. compile 'com.github.Cutta:GifView:1.1'
布局和代码中设置:
xmlns:custom="http://schemas.android.com/apk/res-auto"
<com.cunoraz.gifview.library.GifView
android:id="@+id/gif"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
custom:gif="@drawable/gif1"/>
GifView gifView = (GifView) view.findViewById(R.id.gif);
gifView.pause(); //默认为自动播放,可以手动设置 custom:paused="true"

Eclipse中使用

1、把独杆司令GifView拷到项目中
2、把自定义属性拷到attrs.xml中
  1. <declare-styleable name="GifView">
  2. <attr name="gif" format="reference" />
  3. <attr name="paused" format="boolean" />
  4. </declare-styleable>
3、在布局和代码中使用
xmlns:custom="http://schemas.android.com/apk/res/com.bqt"
  1. <com.bqt.GifView
  2. android:id="@+id/gif"
  3. android:layout_width="wrap_content"
  4. android:layout_height="wrap_content"
  5. custom:gif="@drawable/gif" />
没啥好说的,简单实用。

附件列表

动态图片 gif的更多相关文章

  1. Android—基于GifView显示gif动态图片

    android中显示gif动态图片用到了开源框架GifView 1.拷GifView.jar到自己的项目中. 2.将自己的gif图片拷贝到drawable文件夹 3.在xml文件中设置基本属性: &l ...

  2. iOS 播放GIF动态图片!!!!!

    ////////////////////////////////////////////////////////////////////////////////////////// ////  Vie ...

  3. python3抓取异步百度瀑布流动态图片(二)get、json下载代码讲解

    制作解析网址的get def gethtml(url,postdata): header = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; ...

  4. Android之动态图片

    在Android中,比起静态图片来动态图片会更加生动更加酷炫,因为这种视觉效果,你应该会发现我们手机中大多数应用软件的导航页面也都是采用动态图片来展示.动态图片的格式有gif.png格式等等. 我们就 ...

  5. HTML中动态图片切换JQuery实现

    相信很多同学都注意到了,各大新闻或者娱乐网站都含有动态图片切换,那个漂亮的感觉让刚刚学习html的人,都非常好奇和心动.那下面就让我们看一下到底如何实现动态图片切换呢?看一下百度贴吧的效果图吧~ // ...

  6. winfrom播放动态图片

    winfrom是不能直接加载的动态图片的.只能够自己写方法实现. 具体代码如下: using System; using System.Collections.Generic; using Syste ...

  7. Android中显示gif动态图片

    在android中显示一个静态图片比如png jpg等等都很方便,但是如果要显示一个gif 动态图片就需要进行一些处理. 本文是采用自定义view 然后进行重新onDraw方法来实现 首先自定义Vie ...

  8. 用jQuery实现切换动态图片

    1.实现动态图片的切换只需要改变目标图片的路径

  9. 简单的Django向HTML展示动态图片 案例——小白

    目标:通过Django向HTML传送图片展示 我的天哪,真是膈应人,网上的案例都不适合我,感觉所有的解决办法在我这里都不行. 好吧~ 是我菜,看不懂人家的代码,那句话叫啥来着?一本好经被傻和尚念歪了. ...

  10. 【Mac】使用PicGIF制作gif动态图片

    动态图片是我们常常需要的,mac系统下制作gif图片,可以使用PicGIF,AppStore中有一个简单版本免费的 环境与工具 1.mac系统 2.PicGIF Lite(可以在AppStore下载) ...

随机推荐

  1. Get URL parameters & values with jQuery

    原文: http://jquery-howto.blogspot.jp/2009/09/get-url-parameters-values-with-jquery.html In this post, ...

  2. 浮点与整形在GUI下的相关思考

    平时不接触绘图,似乎感觉不到浮点和整形所带来的区别,这次项目中意外的碰到了浮点与整形进行迁移的工作.因此写点心得,让自己以后也可以看看. 用浮点作图有个最大的弊端就是边界情况,比如你需要在点(20,2 ...

  3. getUrlParam,jQuery中的URL参数获取

    大家经常会需要在一段URL中截取到自己所需参数的值,下面的方法也许能帮到您: $.getUrlParam = function(name){ var reg = new RegExp("(^ ...

  4. Thinkphp 验证码、文件上传

    一.验证码 验证码参数 例题:登录时验证下验证码 LoginController.class.php <?php namespace Home\Controller; use Think\Con ...

  5. C程序设计语言练习题1-23

    练习1-23 编写一个删除C语言程序中所有的注释语句.要正确处理带引号的字符串与字符常量.在C语言中,注释不能嵌套. 代码如下: #include <stdio.h> // 包含标准库的信 ...

  6. USB方向

    Because the host is always the bus master, it is easy to remember USB direction: OUT means from the ...

  7. ViewPage和ActionBar打造滑动视图

    滑动效果非常流畅,可以将页签放置到ActionBar上,点击页签可以切换ViewPage,滑动ViewPage会同步更显Tabs. main.xml <?xml version="1. ...

  8. haskell趣学指南笔记1

    网址:http://learnyouahaskell.com/ 中文版:http://learnyouahaskell-zh-tw.csie.org/zh-cn/ready-begin.html 在 ...

  9. Wormholes 最短路判断有无负权值

    Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes ...

  10. 双向队列 STL

    题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操作.现在给你一系列的操作,请输出最后队列的状态:命令格式:LIN X  X表示一个整数,命 ...