如何识别webp图片是静态图片还是动画图片?
How to identify whether webp image is static or animated?
我正在开发一个用户可以上传 webp
图片的项目。我知道如何将 webp
图像转换为 jpg/png,但我仍然不知道如何识别 webp
图像是静态(非动画)还是动画。
我想识别它们,因为我使用不同的命令进行转换:
非动画 webp 到 jpg 的命令:
dwebp nonanimated.webp -o jpg.jpg
动画 webp 到非动画 webp 的命令(需要第二帧):
webpmux -get frame 2 animated.webp -o nonanimated.webp
但是我找不到一个命令可以处理这两种情况。
我在服务器端使用 PHP,在前端使用 HTML 和 Javascript。
经过大量调查,我发现动画 webp
图像总是包含一些字符串,当在文本编辑器中打开时,非动画图像则不会。字符串是 ANMF
和 ANIM
。我在我拥有的所有 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;
}
?>
在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();
}
但是如果大图像 PHP
和 Javascript
效果不佳,那么最好的解决方案是使用 Shell Script
,如果你有 Ubuntu
.
在 Shell 脚本中:
echo $(grep -c "ANMF" ~/animated.webp)
return 如果非动画则为 0,否则为动画非零值。
Webp header、ANIMATION 等中有标志。检查它的小函数:
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;
}
ANIM 和 ANMF 来自下一个区块 headers.
根据Sven Liivak的isWebpAnimated()
...有一个小错误。
fseek($fh, 16);
应该是:
fseek($fh, 20);
因为位置 16
是 VP8X
中的 chunk_size
位置。
但是我们需要 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;
}
这是我的 java 代码,对我有用。
static boolean isWebpAnimated(InputStream in) {
boolean result = false;
try {
in.skip(12);
byte[] buf = new byte[4];
int i = in.read(buf);
if ("VP8X".equals(new String(buf, 0, i))) {
in.skip(12);
result = (in.read(buf) == 4 && (buf[3] & 0x00000002) != 0);
}
} catch (Exception e) {
} finally {
try {
in.close();
} catch (Exception e) {
}
}
return result;
}
我正在开发一个用户可以上传 webp
图片的项目。我知道如何将 webp
图像转换为 jpg/png,但我仍然不知道如何识别 webp
图像是静态(非动画)还是动画。
我想识别它们,因为我使用不同的命令进行转换:
非动画 webp 到 jpg 的命令:
dwebp nonanimated.webp -o jpg.jpg
动画 webp 到非动画 webp 的命令(需要第二帧):
webpmux -get frame 2 animated.webp -o nonanimated.webp
但是我找不到一个命令可以处理这两种情况。
我在服务器端使用 PHP,在前端使用 HTML 和 Javascript。
经过大量调查,我发现动画 webp
图像总是包含一些字符串,当在文本编辑器中打开时,非动画图像则不会。字符串是 ANMF
和 ANIM
。我在我拥有的所有 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;
}
?>
在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();
}
但是如果大图像 PHP
和 Javascript
效果不佳,那么最好的解决方案是使用 Shell Script
,如果你有 Ubuntu
.
在 Shell 脚本中:
echo $(grep -c "ANMF" ~/animated.webp)
return 如果非动画则为 0,否则为动画非零值。
Webp header、ANIMATION 等中有标志。检查它的小函数:
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;
}
ANIM 和 ANMF 来自下一个区块 headers.
根据Sven Liivak的isWebpAnimated()
...有一个小错误。
fseek($fh, 16);
应该是:
fseek($fh, 20);
因为位置 16
是 VP8X
中的 chunk_size
位置。
但是我们需要 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;
}
这是我的 java 代码,对我有用。
static boolean isWebpAnimated(InputStream in) {
boolean result = false;
try {
in.skip(12);
byte[] buf = new byte[4];
int i = in.read(buf);
if ("VP8X".equals(new String(buf, 0, i))) {
in.skip(12);
result = (in.read(buf) == 4 && (buf[3] & 0x00000002) != 0);
}
} catch (Exception e) {
} finally {
try {
in.close();
} catch (Exception e) {
}
}
return result;
}