如何识别webp图像是静态的还是动画的?

har*_*rma 3 javascript php webp

我正在做一个项目,用户可以在其中上传webp图像。我知道如何将webp图像转换为 jpg/png。但我陷入了困境,如何识别webp图像是静态(非动画)还是动画。我想确定,因为我正在使用这样的命令进行转换:

非动画 webp 到 jpg- 的命令

dwebp nonanimated.webp -o jpg.jpg

用于动画 webp 到非动画 webp 的命令(需要第二帧) -

webpmux -get frame 2 animated.webp -o nonanimated.webp

但是我没有找到一个可以处理这两种情况的命令。所以我想识别 webp 图像。

PHP在服务器端使用HTML,前端使用和Javascript

Sve*_*vak 7

Webp 标头、动画等中有标志。检查它的小函数:

function isWebpAnimated($fn){
  $result = false;
  $fh = fopen($fn, "rb"); 
  fseek($fh, 12);
  if(fread($fh, 4) === 'VP8X'){
    fseek($fh, 16);
    $myByte = fread($fh, 1);
    $result = ((ord($myByte) >> 1) & 1)?true:false;
  }
  fclose($fh);
  return $result;
}
Run Code Online (Sandbox Code Playgroud)

ANIM 和 ANMF 来自下一个块头。

RIFF集装箱规格


har*_*rma 5

经过大量调查,我发现动画webp图像总是包含一些字符串,当在文本编辑器中打开时,非动画图像没有。字符串是ANMFANIM。我在我拥有的所有 webp 图像中检查了这些字符串。所以这对我来说是完美的。以下是PHP,Javascript和中的一些解决方案Shell Script

在 PHP 中:

<?php
function isWebpAnimated($src){
    $webpContents = file_get_contents($src);
    $where = strpos($webpContents, "ANMF");
    if ($where !== FALSE){
        // animated
        $isAnimated = true;
    }
    else{
        // non animated
        $isAnimated = false;
    }
    return $isAnimated;
}
?>
Run Code Online (Sandbox Code Playgroud)

在 JavaScript 中:

function isAnimatedGif(src) {
    var request = new XMLHttpRequest();
    request.open('GET', src, true);
    request.addEventListener('load', function () {
        if(request.response.indexOf("ANMF") != -1){
            // animated
            alert(true);
        }
        else{
            // non animated
            alert(false);
        }
    });
    request.send();
}
Run Code Online (Sandbox Code Playgroud)

但是如果图像很大PHP并且Javascript效果不佳,那么最好的解决方案是使用Shell Script,如果您有Ubuntu.

在 Shell 脚本中:

echo $(grep -c "ANMF" ~/animated.webp)
Run Code Online (Sandbox Code Playgroud)

如果非动画,则返回 0,否则动画的非零值。

  • 此外,它对于任何大小的文件都同样快速,因为您只需要读取文件开头的几个字节。 (3认同)
  • 请注意,当文件中的某些字节恰好包含与字符串“ANMF”相同的二进制值时,此解决方案在极少数情况下会产生误报。按照其他答案中的建议解析 webp 标头会更可靠。 (2认同)

小智 5

根据Sven LiivakisWebpAnimated()...有一个小错误。

fseek($fh, 16);

应该:

fseek($fh, 20);

因为position16就是chunk_size中的位置VP8X。但我们需要flag的位置是20

固定功能:

function isWebpAnimated($fn){
  $result = false;
  $fh = fopen($fn, "rb"); 
  fseek($fh, 12);
  if(fread($fh, 4) === 'VP8X'){
    fseek($fh, 20);
    $myByte = fread($fh, 1);
    $result = ((ord($myByte) >> 1) & 1)?true:false;
  }
  fclose($fh);
  return $result;
}
Run Code Online (Sandbox Code Playgroud)