Gallery3d中本来是不支持Gif动画显示的,它将gif图片作为Bitmap显示,所以我们只能看到静态的图片。但是我们可以通过一些第三方解析包添加这一功能。
添加GIF解析器
要显示Gif动态图片,必须获取每张动画的每一帧以及每一帧之间的间隔。google code上有一个项目
http://code.google.com/p/gifview/可以提供这些功能。下载源代码包,然后主要利用GifAction.java GifDecoder.java GifFrame.java这三个文件。
这三个文件的功能分别为:
GifAction : 提供解析完的回调函数
GifDecoder : 完成将Gif图片解析成Bitmap的功能
GifFrame: 每一帧的封装,包含这一帧的Bitmap以及持续时间。
将这些文件放入com.cooliris.media.gif包内即可。
GifTextureGroup
下来,建立一个GifTextureGroup类,用来存储获取到的Bitmap,并用gallery3d已经有的类BitmapTexture来管理。源代码如下:
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.cooliris.media.gif;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
import com.cooliris.media.BitmapTexture;
import com.cooliris.media.RenderView;
import com.cooliris.media.Texture;
import android.util.Log;
public class GifTextureGroup{
// A simple flexible texture class that enables a Texture from a bitmap.
GifDecoder mGifDecoder;
long mFirstTime = 0;
private List<Texture> mTexutreList = new ArrayList<Texture>();
private static String TAG = "GifTextureGroup";
private boolean mDrawingStarted = false;
private boolean mCoverParsed = false;
int mPeriod = 0;
int [] mDelays = null;
public GifTextureGroup(String filePath, final RenderView view) {
try {
mGifDecoder = new GifDecoder(new FileInputStream(filePath),new GifAction() {
@Override
public void parseOk(boolean parseStatus, int frameIndex) {
if(parseStatus)
{
if(frameIndex != -1)
{
final int index = frameIndex - 1;
GifFrame frame = mGifDecoder.getFrame(index);
Texture texture = new BitmapTexture(frame.image);
view.bind(texture);
view.prime(texture, true);
mTexutreList.add(index, texture);
}
else
{
mPeriod = mGifDecoder.getT();
mDelays = mGifDecoder.getDelays();
mGifDecoder.free();
}
mCoverParsed = true;
}
else
{
Log.e(TAG,"parseStatus Error!!:" + frameIndex);
}
}
});
mGifDecoder.start();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public boolean isLoaded()
{
if(!mGifDecoder.parseOk())
return false;
for(Texture texture : mTexutreList)
{
if(!texture.isLoaded())
return false;
}
return true;
}
public Texture getCurrentTexture()
{
if(!isLoaded())
{
return null;
}
final long interval = System.currentTimeMillis() - mFirstTime;
int time= (int) (interval % mPeriod);
int index = 0;
for(int i=0; i<mDelays.length; i++)
{
if(time < mDelays[i])
{
index = i;
break;
}
else
{
time -= mDelays[i];
}
}
return mTexutreList.get(index);
}
public void start() {
mDrawingStarted = true;
mFirstTime = System.currentTimeMillis();
}
public Texture getCoverTexture() {
if(mCoverParsed)
return mTexutreList.get(0);
return null;
}
public boolean drawinStarted() {
return mDrawingStarted;
}
}
GifTextureGroup的处理很简单,主要是新建一个
GifDecoder并且,给出解析gif完的处理函数。
对解析好的bitmap的处理方式为调用RenderView的bind以及prime方法将他们转为openGl中的texture,以备以后使用。
并且提供了这些接口:
getCoverTexture : 获取第一张的图片,如果没有加载好的话就返回第一张
start : 开始gif动画,以后会根据与第一次画的时间间隔来判断该画第几张了。
drawinStarted : 判断是否已经开始绘制了
getCurrentTexture : 获取当前该画第几张了
isLoaded : 判断是否已经加载完成
将这部分功能加入GridDrawManager中
GridDrawManager的drawFocusItems是用来绘制大图的。在这个函数中需要加入这些语句:
if(displayItem != null && displayItem.isGif())
{
GifTextureGroup textureGroup= displayItem.getTextureGroup(view);
if(i!=0 || !textureGroup.isLoaded())
{
texture = textureGroup.getCoverTexture();
}
else
{
if(!isDrawingGif() || !textureGroup.drawinStarted())//first draw
{
textureGroup.start();
mGifSlot = selectedSlotIndex;
}
texture = textureGroup.getCurrentTexture();
}
}
else
{
texture = displayItem.getScreennailImage(view.getContext());
}
这里是根据所绘制的文件的路径名来判断当前图片是否是gif的,如果是的并且已经加载完成,就会开始绘制。