gpt4 book ai didi

How to identify whether webp image is static or animated?(如何识别WebP图像是静态的还是动态的?)

转载 作者:bug小助手 更新时间:2023-10-25 22:01:45 43 4
gpt4 key购买 nike



I am working on a project where a user can upload webp images. I know how to convert webp images into jpg/png, but am stuck on how to identify whether the webp image is static (non-animated) or animated.

我在一个项目上工作,用户可以上传WebP图像。我知道如何将WebP图像转换为jpg/png,但我不知道如何识别WebP图像是静态的(非动画的)还是动画的。


I want to identify them because I use different commands for conversion:

我想标识它们,因为我使用不同的命令进行转换:


Command for non-animated webp to jpg:

将非动画WebP转换为jpg的命令:


dwebp nonanimated.webp -o jpg.jpg

非动画dwebp.webp-o jpg.jpg


Command for animated webp to non-animated webp (takes 2nd frame):

动画WebP到非动画WebP的命令(第2帧):


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

Webpmux-获取帧2动画.webp-o非动画.webp


But I cannot find a single command that handle both cases.

但我找不到一个能同时处理这两种情况的命令。


I am using PHP on the server side, and HTML and Javascript for frontend.

我在服务器端使用的是PHP,前端使用的是HTML语言和Java脚本。


更多回答

As far as I know it's only GIF that can animate

据我所知,只有GIF才能动画化

If ^^ is correct you can use this code from php manual secure.php.net/manual/en/function.imagecreatefromgif.php#59787

如果^^是正确的,您可以使用php手册secure.php.net/manual/en/function.imagecreatefromgif.php#59787中的代码

This code only checks gif not webp. Webp also can animate, Please check this using Chrome Browser cloudinary.com/blog/…

此代码只检查gif而不是WebP。WebP也可以动画化,请使用Chrome浏览器Cloudinary.com/Blog/…查看

Can you not check if the file has frames? If it has more than 1 then treat as animated else it must be static...

你能不能不检查文件是否有框架?如果它有1个以上,则视为动画,否则它一定是静态的…

How can i check?

我怎么才能检查呢?

优秀答案推荐

There are flags in Webp header, ANIMATION among others. Small function to check it:

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;
}


ANIM and ANMF are from next chunk headers.

Anim和ANMF来自下一个块标头。



RIFF container specification

RIFF容器规范



After a lot of investigation i found that animated webp images always conatins some string, when open in a text editor and non animated images doesn't. The strings are ANMF and ANIM. I checked these string in all webp images which i have. So this is perfect for me. Here are some solutions in PHP, Javascript and Shell Script:

经过大量调查,我发现当在文本编辑器中打开WebP动画图像时,总是包含一些字符串,而非动画图像则不包含。这些字符串是ANMF和ANIM。我在我拥有的所有WebP图像中检查了这些字符串。所以这对我来说是完美的。以下是一些用PHP、Java脚本和壳牌脚本编写的解决方案:


In PHP:

在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;
}
?>

In Javascript:

在Java脚本中:


function isWebpAnimated(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();
}

But In case of large images PHP and Javascript not working well, So best Solution is to use Shell Script, If you have Ubuntu.

但在大型图像的情况下,PHP和Java无法很好地工作,所以最好的解决方案是使用Shell脚本,如果你有Ubuntu的话。


In Shell Script:

在外壳脚本中:


echo $(grep -c "ANMF" ~/animated.webp)

return 0 if non animated, else non zero value for animated.

如果未设置动画,则返回0,否则返回非零值。


EDIT: In Python

编辑:在Python中


def isWebpAnimated(src):
try:
with open(src, 'rb') as f:
data = f.read()

# Check if the file starts with 'RIFF' and contains 'WEBPVP8' or 'WEBPVP8X'
if data.startswith(b'RIFF') and (b'WEBPVP8' in data or b'WEBPVP8X' in data):
# The 'ANIM' indicating that the given file is Animated
return 1
else:
return 0

except Exception as err:
exit(f"Error Occure: {err}")



According Sven Liivak's isWebpAnimated()... there is a small bug.

根据Sven Liivak的isWebpAnimated().有一个小bug。



fseek($fh, 16);

FSeek($fh,16);



should be:

应该是:



fseek($fh, 20);

FSeek($fh,20);



Because postion 16 is the chunk_size position in VP8X.
But we need the flag position which is at 20.

因为位置16是VP8X中的CHUNK_SIZE位置。但我们需要旗帜的位置在20。



Fixed function:

固定功能:



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;
}


This is my java code, it works for me.

这是我的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;
}


Fixing @ccomangee's solution.
Some static webp images would be detected as animated and can cause issue in the application.

修复@ccomangee的解决方案。某些静态WebP图像会被检测为动画,可能会导致应用程序出现问题。


I had extracted webp frames and saved as webp images and tried to identify by checking VP8X signature and it exists in given position although It is static image. So if there is VP8X it does not mean that the image would be animated having more than one frames.

我提取了webp帧并保存为webp图像,并试图通过检查VP8X签名来识别,它存在于给定的位置,尽管它是静态图像。因此,如果有VP8X,这并不意味着图像将被动画具有多个帧。


I tried few images with my solution and the result is below:

我用我的解决方案尝试了几个图像,结果如下:


                             riff   webp  vp8*   anim
OK(anim-trans).webp: [ RIFF | WEBP | VP8X | ANIM ]
Cuppy(static-trans).webp: [ RIFF | WEBP | VP8L | NA? ]
glass(anim-solid).webp: [ RIFF | WEBP | VP8X | ANIM ]
sunset(anim-trans).webp: [ RIFF | WEBP | VP8X | ANIM ]
atom(anim_solid).webp: [ RIFF | WEBP | VP8X | ANIM ]
spread(anim-trans).webp: [ RIFF | WEBP | VP8X | ANIM ]
heart(static-trans).webp: [ RIFF | WEBP | VP8X | NA? ]
ludo(static-trans).webp: [ RIFF | WEBP | VP8X | NA? ]
scene(static_solid).webp: [ RIFF | WEBP | VP8 | NA? ]

Here all images are named according to its type.
anim-trans: animated image contains transparency (alpha channel support)
anim-solid: animated image having no transparency
static-trans and static-solid are static images.

这里所有的图像都是根据其类型命名的。动画-变换:动画图像包含透明度(Alpha通道支持)动画-实体:没有透明度的动画图像静态-变换和静态-实体是静态图像。


VP8L is loseless webp and VP8X contains extended features.
VP8 is surely static image.

VP8L是无损耗的WebP,而VP8X包含扩展功能。VP8肯定是静态图像。


If VP8X exists it could be static or animated most images would be animated.

如果VP8X存在,它可以是静态的,也可以是动画的,大多数图像都是动画的。


The solution is

解决方案是


Read 4 bytes -> 'RIFF'
Skip 4 bytes
Read 4 bytes -> 'WEBP'
Read 4 bytes -> 'VP8X' / 'VP8L' / 'VP8'
skip 14 bytes
Read 4 bytes -> 'ANIM'

读取4字节->‘RIFF’跳过4字节读取->‘WebP’读取4字节->‘VP8X’/‘VP8L’/‘VP8’跳过14字节读取4字节->‘动画’


Java Code:

Java代码:


 public static boolean check(File file) {
boolean riff = false;
boolean webp = false;
boolean vp8x = false;
boolean anim = false;
try (InputStream in = new FileInputStream(file)) {

byte[] buf = new byte[4];
int i = in.read(buf); // 4

if(buf[0] == 0x52 && buf[1] == 0x49 && buf[2]==0x46 && buf[3] == buf[2] )
riff = true;

in.skip(4); // ???? (8+)
i = in.read(buf); // (12+)
if(buf[0] == 0x57 && buf[1] == 0x45 && buf[2]==0x42 && buf[3] == 0x50 )
webp = true ;

i = in.read(buf); // (16+)
if(buf[0] == 0x41 && buf[1] == 0x4e && buf[2]==0x49 && buf[3] == 0x4d );
vp8x = true;

in.skip(14); // then next 4 should contain ANIM - 41 4e 49 4d
i = in.read(buf);
if(buf[0] == 0x41 && buf[1] == 0x4e && buf[2]==0x49 && buf[3] == 0x4d )
anim = true;

} catch (Exception e) {
System.out.println("errrrrr "+e.getMessage());
}
return riff && webp && anim;

}

you can directly read WEBP by skipping 8 bytes then count and skipp all chunks before ANIM and read that position if ANIM exist then its animated webp image else static.

您可以通过跳过8个字节直接读取WebP,然后计算和跳过动画之前的所有块,并读取该位置,如果动画存在,则其动画WebP图像否则为静态。


File layout of webp images
https://developers.google.com/speed/webp/docs/riff_container#example_file_layouts

WebP图像https://developers.google.com/speed/webp/docs/riff_container#example_file_layouts的文件布局


Ref: Google WEBP specification https://developers.google.com/speed/webp/docs/riff_container

参考:Google WebP规范https://developers.google.com/speed/webp/docs/riff_container



def is_webp_animation(img_content):
# https://developers.google.com/speed/webp/docs/riff_container#extended_file_format
# webp Animation image.
return len(img_content) > 20 and img_content[0:4] == b'RIFF' and img_content[8:12] == b'WEBP' \
and img_content[12:16] == b'VP8X' \
and int.from_bytes(img_content[20:21], 'little') & 2 == 2


This is my solution in BASH (Linux). Work in Debian 12 without any needed softwares added. Search and COPY animated webp files to desktop. It is easy to modify my script to accommodate your need. Some idea come from here.

这是我在Bash(Linux)中的解决方案。在Debian 12中工作,不需要添加任何需要的软件。搜索动画WebP文件并将其复制到桌面。它很容易修改我的脚本,以适应您的需要。一些想法是从这里产生的。


#!/bin/bash
file=$(zenity --file-selection --filename=$HOME/ --title="Choose a directory to convert all file" --directory)
rm "/dev/shm/findaniwebp.txt" 2> /dev/null
rm "/dev/shm/findfiles.txt" 2> /dev/null
find "$file" -iname '*.webp' >> "/dev/shm/findfiles.txt" 2>/dev/null

{
result=0
input="/dev/shm/findfiles.txt"
while IFS= read -r "line"
do
result=$(echo $(grep -c "ANMF" "$line"))
if [ "$result" -ge 10 ]; then
echo "Animated webp is found !"
echo $line
echo $line >> "/dev/shm/findaniwebp.txt"
fi
done < "$input"
}

if [ ! -f "/dev/shm/findaniwebp.txt" ]
then
aniwebp=0
else
aniwebp=$(wc -l < "/dev/shm/findaniwebp.txt")
echo "Finding finish (webp only) , with file to move : $aniwebp"
fi

if [ "$aniwebp" -ge "1" ]; then
if zenity --no-wrap --question --text="Do you want to COPY theseS fileS to $HOME/Desktop ?"
then
{
input="/dev/shm/findaniwebp.txt"
while IFS= read -r "line"
do
cp "$line" "$HOME"/Desktop
echo file moved...
done < "$input"
}
fi
else
echo "NO animated webp found!"
fi

rm "/dev/shm/findaniwebp.txt" 2> /dev/null
rm "/dev/shm/findfiles.txt" 2> /dev/null
read -n 1 -s -r -p "Press ENTER key to exit !"
exit


I apologize for joining this discussion late, but I'm also seeking a Python-based solution for offline use.

很抱歉这么晚才参加这个讨论,但我也在寻找一种脱机使用的基于Python的解决方案。


Although I'm not well-versed in PHP or JavaScript, I do have some knowledge of Python. Here's what I've discovered: you can determine whether a WebP image is an animation or a static image using the Python Imaging Library (PIL).

虽然我不太精通PHP或JavaScript,但我对Python有一定的了解。下面是我的发现:您可以使用Python成像库(PIL)来确定WebP图像是动画图像还是静态图像。


To count the number of frames in a WebP image and identify animations, you can utilize PIL's Image and ImageSequence modules. Here's a Python script to accomplish this:

要计算WebP图像中的帧数量并识别动画,可以使用PIL的Image和ImageSequence模块。以下是实现这一点的一个Python脚本:


from PIL import Image, ImageSequence

def is_animation(file):
image = Image.open(file)
count = 0
for frame in ImageSequence.Iterator(image):
count += 1
return count > 1

By using this code, you can call the is_animation function, passing the file path as an argument. If the image contains more than one frame, the function will return True, indicating that it's an animation; otherwise, it will return False for a static image.

通过使用此代码,您可以调用is_Animation函数,并将文件路径作为参数传递。如果图像包含多个帧,该函数将返回True,指示它是动画;否则,它将为静态图像返回False。


更多回答

?true:false can be removed, it's not necessary to change a boolean to a boolean.

?TRUE:FALSE可以删除,不需要将布尔值更改为布尔值。

Note that this solution will produce false-positives in rare cases when some bytes in the file happen to contain the same binary values as the string "ANMF". Parsing the webp header as suggested in the other answers would be more reliable.

请注意,当文件中的某些字节恰好包含与字符串“ANMF”相同的二进制值时,此解决方案将在极少数情况下产生误报。按照其他答案中的建议解析WebP报头会更可靠。

Also it would work equally fast for files of any size, since you only need to read a few bytes at the very beginning of the file.

此外,对于任何大小的文件,它的运行速度都一样快,因为您只需要在文件的最开始读取几个字节。

In PHP, the if, else and return blocks can be replaced by return ($where !== FALSE);.

在PHP中,IF、ELSE和RETURN块可以替换为RETURN($WHERE!==FALSE);。

this is the correct answer. the other one always returns true for any webp

这是正确的答案。对于任何WebP,另一个总是返回TRUE

some webp contains VP8L

一些WebP包含VP8L

I had extracted frames from webp and those static frames are detected as animated according to this function. I think we should also check for ANIM header

我已经从WebP中提取了帧,根据这个函数,这些静态帧被检测为动画。我想我们也应该检查一下动漫标题

43 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com