最近データフォルダでアニメーションGIF画像の再生に対応してアップデートしました(^O^)
Googleでも画像検索で最近Gif画像の再生に対応しましたね(^^)
データフォルダでは、以前からアニメーションGIF画像の再生には対応していましたが、
ViewPagerタイプの画像表示画面では対応していなかったため、
ImageViewを拡張したGifImageViewを作成し派生させて利用しました。
アニメーションGif画像を表示する方法は2通りあるため、
ここではその2つのGifImageViewを紹介したいと思います。
・Movieクラスを使用したアニメーションGIF画像の再生
まず、ImageViewを拡張したGifImageView内に
アニメーションGIF画像再生用のMovieクラスのメンバ変数を持たせ、
GIF画像をInputStreamとして渡してMovieクラスにdecodeStreamで読み込ませて再生させます。
割りと簡単に実装ができ、Movieクラスの動作はNativeであるため、軽快に動作しますが、全てのGIF画像には対応していないため、その場合にはGifDecoderを使用して動作させると良いかと
思います。
Googleでも画像検索で最近Gif画像の再生に対応しましたね(^^)
ViewPagerタイプの画像表示画面では対応していなかったため、
ImageViewを拡張したGifImageViewを作成し派生させて利用しました。
アニメーションGif画像を表示する方法は2通りあるため、
ここではその2つのGifImageViewを紹介したいと思います。
・Movieクラスを使用したアニメーションGIF画像の再生
・GifDecoderを使用したアニメーションGIF画像の再生
Movieクラスを使用したアニメーションGIF画像の再生
public class GifImageView extends ImageView
{
private Movie mMovie;
private long mMoviestart;
public GifImageView(Context context, InputStream stream) {
super(context);
mMovie = Movie.decodeStream(stream);
}
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.TRANSPARENT);
super.onDraw(canvas);
final long now = SystemClock.uptimeMillis();
if (mMoviestart == 0) {
mMoviestart = now;
}
final int relTime = (int)((now - mMoviestart) % mMovie.duration());
mMovie.setTime(relTime);
mMovie.draw(canvas, 10, 10);
this.invalidate();
}
}
まず、ImageViewを拡張したGifImageView内に
アニメーションGIF画像再生用のMovieクラスのメンバ変数を持たせ、
GIF画像をInputStreamとして渡してMovieクラスにdecodeStreamで読み込ませて再生させます。
割りと簡単に実装ができ、Movieクラスの動作はNativeであるため、軽快に動作しますが、全てのGIF画像には対応していないため、その場合にはGifDecoderを使用して動作させると良いかと
思います。
GifDecoderを使用したアニメーションGIF画像の再生
public class GifImageView extends ImageView
{
private boolean mIsPlayingGif = false;
private GifDecoder mGifDecoder;
private Bitmap mTmpBitmap;
final Handler mHandler = new Handler();
final Runnable mUpdateResults = new Runnable() {
public void run() {
if (mTmpBitmap != null && !mTmpBitmap.isRecycled()) {
GifDecoderView.this.setImageBitmap(mTmpBitmap);
}
}
};
public GifImageView(Context context, InputStream stream) {
super(context);
playGif(stream);
}
private void playGif(InputStream stream) {
mGifDecoder = new GifDecoder();
mGifDecoder.read(stream);
mIsPlayingGif = true;
new Thread(new Runnable() {
public void run() {
final int n = mGifDecoder.getFrameCount();
final int ntimes = mGifDecoder.getLoopCount();
int repetitionCounter = 0;
do {
for (int i = 0; i < n; i++) {
mTmpBitmap = mGifDecoder.getFrame(i);
int t = mGifDecoder.getDelay(i);
mHandler.post(mUpdateResults);
try {
Thread.sleep(t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if(ntimes != 0) {
repetitionCounter ++;
}
} while (mIsPlayingGif && (repetitionCounter <= ntimes));
}
}).start();
}
public void stopRendering() {
mIsPlayingGif = true;
}
}
GifDecoderは以下のサイトのソースを使用させてもらって利用しています。
(中身は多少いじってますが(^^;))
画像解析してGIF画像を表示しているため、おそらく大抵のGIF画像の再生が可能です。
動作は少しもっさりしますが、こちらの方が色々とカスタマイズできるかと思います。
Movieクラスで再生できない場合にGifDecoderを使った再生方法を実装しています。
また、GIF画像を拡大/縮小等するために、
Movieクラスで描画しているBitmapを取得して直接描画することで処理を行うようにしていますが、
そのあたりも機会があれば紹介します(*^_^*)
(中身は多少いじってますが(^^;))
動作は少しもっさりしますが、こちらの方が色々とカスタマイズできるかと思います。
最後に
データフォルダではこの2つを組み合わせて、Movieクラスで再生できない場合にGifDecoderを使った再生方法を実装しています。
また、GIF画像を拡大/縮小等するために、
Movieクラスで描画しているBitmapを取得して直接描画することで処理を行うようにしていますが、
そのあたりも機会があれば紹介します(*^_^*)
0 件のコメント:
コメントを投稿