让swing正确显示gif图片
来源:互联网 发布:网络管理工程师招聘 编辑:程序博客网 时间:2024/04/30 02:04
首先需要对Gif这种图片格式有一些基本认识。
第一:Gif由一系列Image组成,也就是桢,Gif动画就是连续地显示这些桢,但是这还不够。
第二:无论某一时刻轮循到哪一桢,第1桢,总是要当作背景画出来,而且第1桢也是所有桢当中最长最高的,它的尺寸也是整个Gif图象的尺寸,位置从(0, 0)开始,其余各桢可能只是描述与相临各桢变化的部分,所以长和高要小且不完整,起始位置是该桢相对整体背景的位置。(这点SWT也是这样做的)
第三:Gif动画连续显示不一定是各个桢轮循单独显示,而是不仅仅显示当前该显示的桢,还要向前追溯到"第一桢",从"第一桢"开始到当前应该显示的桢组成的连续一系列"桢簇",所以某一时刻单单显示背景和当前桢是不够的,而是显示背景和当前"桢簇"。""桢簇""是我自己取的名字,而且我看SWT轮循的例子中并没有用到"桢簇",而是传统的单桢轮循。但是同样的方法对Swing不奏效,现在我对此还不得其解。关于"第一桢",是和com.sun.imageio.plugins.gif.GIFImageMetadata类的disposalMethod属性有关,在SWT中这个属性是org.eclipse.swt.graphics.ImageData.disposalMethod。disposalMethod据我的研究是描述处理桢的方法,常见的disposalMethod取值有none(取值0,不处理)、Background(取值2,背景)两种,所谓的当前桢的"第一桢"就是向前追溯到最近的disposalMethod取值为2的那一桢的下一桢,也就是说或者"第一桢"的前一桢的disposalMethod取值为2,或者"第一桢"就是Gif索引为2的桢,因为Gif的第1桢总要当背景显示。
第四:桢的元数据在SWT中用org.eclipse.swt.graphics.ImageData类封装,在Swing中对应的是com.sun.imageio.plugins.gif.GIFImageMetadata(可是截止到JDK6.0 u11,这个类的版本号还是0.5,有些另人失望:(),可以通过次类获取到delayTime这个属性,也就是下一桢的间隔时间,但是有很多Gif,这个值总是0,所以Swing显示频率相当的快。
下面为处理代码:
public class GifComponent extends JComponent { private static final long serialVersionUID = 1L; private GifBean[] gifBeans; private Map<Integer, Integer[]> gifBeanMap = new HashMap<Integer, Integer[]>(); private int index = 0; private int delayFactor; private Timer timer; /** * * @param gifFile * @param delayFactor * 显示gif每帧图片的时间因子 */ public GifComponent(File gifFile, int delayFactor) {setDelayFactor(delayFactor);setGifFile(gifFile); } /** * 设置Gif文件 * * @param gifFile */ public void setGifFile(File gifFile) {ImageReader reader = null;try { ImageInputStream imageIn = ImageIO.createImageInputStream(gifFile); Iterator<ImageReader> iter = ImageIO .getImageReadersByFormatName("gif"); if (iter.hasNext()) {reader = iter.next(); } reader.setInput(imageIn, false); gifBeanMap.clear(); gifBeans = new GifBean[reader.getNumImages(true)]; GIFImageMetadata meta = null; for (int i = 0; i < gifBeans.length; i++) {meta = (GIFImageMetadata) reader.getImageMetadata(i);gifBeans[i] = new GifBean();gifBeans[i].image = reader.read(i);gifBeans[i].x = meta.imageLeftPosition;gifBeans[i].y = meta.imageTopPosition;gifBeans[i].width = meta.imageWidth;gifBeans[i].height = meta.imageHeight;gifBeans[i].disposalMethod = meta.disposalMethod;gifBeans[i].delayTime = meta.delayTime == 0 ? 1: meta.delayTime; } for (int i = 1; i < gifBeans.length; i++) {if (gifBeans[i].disposalMethod == 2) { gifBeanMap.put(new Integer(i), new Integer[] { i }); continue;}int firstIndex = getFirstIndex(i);List<Integer> list = new ArrayList<Integer>();for (int j = firstIndex; j <= i; j++) { list.add(j);}gifBeanMap.put(new Integer(i), list.toArray(new Integer[] {})); }} catch (IOException e) { e.printStackTrace();}setTimer(); } private synchronized void setTimer() {if (timer != null) { timer.cancel();}timer = new Timer("show gif");timer.schedule(new TimerTask() { @Override public void run() {repaint();try { Thread.sleep(gifBeans[index].delayTime * delayFactor);} catch (InterruptedException e) {}index++;if (index >= gifBeans.length) { index = 0;} }}, 0, 1); } /** * 设置时间因子 * * @param delayFactor */ public void setDelayFactor(int delayFactor) {this.delayFactor = delayFactor; } @Override protected void paintComponent(Graphics g) {g.drawImage(gifBeans[0].image, gifBeans[0].x, gifBeans[0].y, this);if (index > 0) { Integer[] array = gifBeanMap.get(index); for (Integer i : array) {g.drawImage(gifBeans[i].image, gifBeans[i].x, gifBeans[i].y,this); }} } private int getFirstIndex(int index) {int tempIndex = index;while (tempIndex > 1) { if (tempIndex - 1 > 0 && gifBeans[tempIndex - 1].disposalMethod == 2) {return index; } tempIndex--;}return tempIndex; } /** * 用于保持gif每帧图片的信息 */ public class GifBean {public BufferedImage image;public int x;public int y;public int width;public int height;public int disposalMethod;public int delayTime; }}
原文参考:http://space.itpub.net/13685345/viewspace-514315
- 让swing正确显示gif图片
- 让swing正确显示gif图片
- Swing正确显示Gif
- swing显示gif图片
- Java swing显示gif
- swing 显示gif图
- 如何让你的Android显示gif格式的图片
- 如何让WebView显示gif格式的图片
- 如何让你的 Android 显示gif格式的图片
- swing中如何让表格中显示图片
- VC显示GIF图片
- symbian-GIF图片显示
- Winform 显示Gif图片
- gif动态图片显示
- VC显示GIF图片
- 动态显示图片gif
- android 显示gif图片
- UIWebView显示gif图片
- IPC 额外知识
- Create database
- QT应用程序发布及 QT Creator 设置 app ico图标
- magento 配置(一)
- 保险公司理赔作业流程分析
- 让swing正确显示gif图片
- tuxedo 错误号及错误信息描述 tperrno
- DDR测试系列之一——力科DDR2测试解决方案
- Magento 基础学习记录(一)
- qsort() 之 __cdecl
- 基于real6410和android2.1源码的busybox移植
- Js实现主页面中显示/隐藏层的效果
- Android使用ApacheFtpServer实现Ftp服务器
- C语言循环控制详解