32

我有一个动画 gif,我想在页面加载时显示它。当我在浏览器之外查看图像时,图像会无限循环并且工作得很好,但是每当我在浏览器中显示图像时,动画只会循环一次。有没有人有任何使图像无限循环的建议?

目前我这样做只是为了使图像出现,这确实使它出现,但只循环一次:

document.getElementById('ajaxloader').innerHTML = 
    '<img src="images/ajax-loader.gif" title="Loading, please wait..">';
4

6 回答 6

26

我前段时间写的GIF编码器/解码器类也面临同样的问题(并且不时改进)。我昨天才找到解决方案。GIF完全没问题,问题出在现代互联网浏览器方面。受影响的浏览器是 Opera、IE 和 Chrome(未测试其他浏览器)。

经过对此事的一些调查(通过比较循环和非循环图像),我发现这些浏览器的GIF解码器忽略了GIF文件中的循环参数。相反,它们依赖于GIF文件第一帧中未记录的应用程序扩展。

所以解决方案是在第一帧图像数据之前添加这个扩展命令。添加这个块:

0x21,0xFF,0x0B,"NETSCAPE","2.0",0x03,0x01,0x00,0x00,0x00

这将迫使浏览器无休止地循环。

这是一个例子:

循环

十六进制视图,以便您查看它是如何添加的:

十六进制

GIF对插入/重新排序非图像数据块不敏感,因此您可以将其插入到任何其他扩展之间的任何位置的第一张图像之前。我把它直接放在标题+调色板之后。这可以用C++或任何其他语言来完成(不需要重新编码)。有关更多信息,请参阅:


[里德邓克尔编辑]

您也可以使用十六进制编辑器手动完成。我在 macOS Sierra 上使用了“Hex Fiend”。

21 F9在十六进制的开头部分搜索(这是标题)。在上面的照片中,它是21 F9 04 04 00 00 00 00。您的可能略有不同,但请注意它出现在 之前2C,它标志着图像块的开始。

21 F9... 部分之前,插入以下十六进制,在上图中标记为“应用程序扩展”:

21 FF 0B 4E 45 54 53 43 41 50 45 32 2E 30 03 01 00 00 00

保存并测试它。

Spektre 的插件:当心:21 F9标记 gfx 扩展块是可选的,因此它可能不会出现在所有或任何帧中(但现在这真的很少见)。

于 2016-06-28T17:41:01.140 回答
22

您可以使用gifsicle 命令行工具来处理动画 gif 并添加与所有浏览器兼容的正确循环:

Animation options: -l, --loopcount[=N] Set loop extension to N (default forever).

所以在终端我做:

$ gifsicle --loopcount problem.gif > fixed.gif

它生成了一个新的动画 GIF,可以在 Chrome 和 Firefox 以及 Safari 中运行。

于 2017-04-06T11:15:16.110 回答
8

使用 ImageMagick,通常预装:

convert -loop 0 bad.gif good.gif
于 2018-07-30T19:25:51.523 回答
2

似乎Gimp将允许您导出可以正确循环的 gif。只需打开 gif,然后“文件”>“导出为”并选中“作为动画”和“永远循环”复选框。我不知道这是否会像Spektre 的回答那样更新文件,但我的测试图像在 FireFox 60.0b8(64 位)、Chrome 版本 65.0.3325.181(官方构建)(64 位)和 Safari 版本 9.1 中正确循环.1 (11601.6.17)。永远的gimp循环

于 2018-04-10T23:07:30.947 回答
1

您可以声明有限数量的循环,也可以让电影永远循环。只要页面在屏幕上,INFINITE(或 -1)就会一遍又一遍地循环播放电影。例如,此代码生成连续循环的电影:

<img 
  src="../graphics/moonflag.mpg" 
  dynsrc="../graphics/moonflag.mpg"
  loop=infinite
  alt="Astronauts on the moon">

资源

于 2013-08-21T08:59:02.263 回答
1

根据 Spektre 的回答编写了 PHP gif 修复程序:

/**
 * gif image loop fixer, prints image full url
 * 
 * as this is written as a part of framework, there are some config options
 */

// put your images absolute path here eg '/var/www/html/www.example.com/images/'
// or use autodetection below
$GLOBALS['config']['upload_path'] = str_replace("\\", "/", trim(getcwd(), " /\\")).'/images/';

// put your images relative/absolute url here, eg 'http://www.example.com/images/';
$GLOBALS['config']['upload_url'] = '/images/';

function _ig($image){

    $image_a = pathinfo($image);

    $new_filename = $GLOBALS['config']['upload_path'].$image_a['dirname'].'/_'.$image_a['filename'].'.'.$image_a['extension'];
    $new_url = $GLOBALS['config']['upload_url'].$image_a['dirname'].'/_'.$image_a['filename'].'.'.$image_a['extension'];

    if ($image_a['extension'] == 'gif'){

        if (!file_exists($new_filename)){

            // load file contents
            $data = file_get_contents($GLOBALS['config']['upload_path'].$image);

            if (!strstr($data, 'NETSCAPE2.0')){

                // gif colours byte
                $colours_byte = $data[10];

                // extract binary string
                $bin = decbin(ord($colours_byte));
                $bin = str_pad($bin, 8, 0, STR_PAD_LEFT);

                // calculate colour table length
                if ($bin[0] == 0){
                    $colours_length = 0;
                } else {
                    $colours_length = 3 * pow(2, (bindec(substr($bin, 1, 3)) + 1)); 
                }

                // put netscape string after 13 + colours table length
                $start = substr($data, 0, 13 + $colours_length);
                $end = substr($data, 13 + $colours_length);

                file_put_contents($new_filename, $start . chr(0x21) . chr(0xFF) . chr(0x0B) . 'NETSCAPE2.0' . chr(0x03) . chr(0x01) . chr(0x00) . chr(0x00) . chr(0x00) . $end);

            } else {

                file_put_contents($new_filename, $data);

            }

        }

        print($new_url);

    } else {

        print($GLOBALS['config']['upload_url'].$image);

    }

}

这会将 image.gif 的副本复制为 _image.gif,并在颜色表之后插入所需的字符串并打印出新的 src url。(首先检查图像是否已经修复。)

用法:

<img src="<?php _ig($image); ?>">

或者

<img src="<?php _ig('image.gif'); ?>">

免责声明:不承担任何责任,我知道这可以优化:)

于 2017-01-12T20:39:08.430 回答