代码之家  ›  专栏  ›  技术社区  ›  doekman

是否可以在客户端检测动态GIF图像?

  •  16
  • doekman  · 技术社区  · 15 年前

    是否可以在客户端检测动态GIF图像?

    在Internet Explorer中,您可以使用 onload 事件,因为它将被解雇 every frame loaded (IE8中的行为发生了变化)。

    但是对于其他浏览器也有办法吗?

    2 回复  |  直到 11 年前
        1
  •  0
  •   Residuum    15 年前

    我不知道在客户方面有什么办法可以做到,但我不确定。您可以做的是解析服务器端的HTML代码和任何引用的GIF,并向这些图像添加一个类。但这并不是真正推荐的,因为它至少涉及一个额外的HTML解析+每个GIF的解析。如你所见 this example in PHP 在CPU负载方面,检查gifs也不是很简单。

        2
  •  14
  •   Will    11 年前

    我刚刚写了一些JS来检测动画礼物。适用于除IE 9以外的大多数现代浏览器。

    免责声明: 只有当图像的域原点与从中加载脚本的页面相同时,此操作才有效。

    有关最新版本的代码,请参见要点: https://gist.github.com/3012623

    function isAnimatedGif(src, cb) {
        var request = new XMLHttpRequest();
        request.open('GET', src, true);
        request.responseType = 'arraybuffer';
        request.addEventListener('load', function () {
            var arr = new Uint8Array(request.response),
                i, len, length = arr.length, frames = 0;
    
            // make sure it's a gif (GIF8)
            if (arr[0] !== 0x47 || arr[1] !== 0x49 || 
                arr[2] !== 0x46 || arr[3] !== 0x38)
            {
                cb(false);
                return;
            }
    
            //ported from php http://www.php.net/manual/en/function.imagecreatefromgif.php#104473
            //an animated gif contains multiple "frames", with each frame having a 
            //header made up of:
            // * a static 4-byte sequence (\x00\x21\xF9\x04)
            // * 4 variable bytes
            // * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)
            // We read through the file til we reach the end of the file, or we've found 
            // at least 2 frame headers
            for (i=0, len = length - 9; i < len, frames < 2; ++i) {
                if (arr[i] === 0x00 && arr[i+1] === 0x21 &&
                    arr[i+2] === 0xF9 && arr[i+3] === 0x04 &&
                    arr[i+8] === 0x00 && 
                    (arr[i+9] === 0x2C || arr[i+9] === 0x21))
                {
                    frames++;
                }
            }
    
            // if frame count > 1, it's animated
            cb(frames > 1);
        });
        request.send();
    }