我能否以编程方式确定 PNG 是否具有动画效果?

2022-08-30 21:05:54

我有PNG(以及JPEG)图像上传到我的网站。

它们应该是静态的(即一个帧)。

APNG这样的东西。

Bouncy ball

(它将在火狐中动画化)。

根据维基百科的文章...

APNG 在 PNG 辅助块中隐藏后续帧,使得不识别 APNG 的应用程序会忽略它们,但除此之外,不会对格式进行任何更改,以允许软件区分动画和非动画图像。

这是否意味着无法确定PNG是否使用代码进行动画处理?

如果可能的话,你能给我指出PHP的正确方向(GD,ImageMagick)吗?


答案 1

APNG图像被设计为“伪装”为PNG,供不支持它们的读者使用。也就是说,如果读者不支持它们,它将只假设它是一个普通的PNG文件,只显示第一帧。这意味着它们具有与PNG(image / png)相同的MIME类型,它们具有相同的幻数(),并且通常它们使用相同的扩展名保存(尽管这不是检查文件类型的好方法)。89 50 4e 47 0d 0a 1a 0a

那么,您如何区分它们呢?APNG中有一个“acTL”块。因此,如果您搜索字符串(或者在十六进制中(块标记(即)之前的4个字节是大字节序格式的块的大小,而不计算字段末尾的大小,标记或CRC32)),您应该相当不错。为了做得更好,请检查此块是否出现在“IDAT”块的第一次出现之前(只需查找)。acTL61 63 54 4C00 00 00 08IDAT

这段代码(取自 http://foone.org/apng/identify_apng.php)将完成以下操作:

<?php
# Identifies APNGs
# Written by Coda, functionified by Foone/Popcorn Mariachi#!9i78bPeIxI
# This code is in the public domain
# identify_apng returns:
# true if the file is an APNG
# false if it is any other sort of file (it is not checked for PNG validity)
# takes on argument, a filename.
function identify_apng($filename)
    {
    $img_bytes = file_get_contents($filename);
    if ($img_bytes)
        {
        if(strpos(substr($img_bytes, 0, strpos($img_bytes, 'IDAT')), 
                 'acTL')!==false)
            {
        return true;
        }
        }
    return false;
    }
?>

答案 2

AFAIK,不支持APNG的库将只采用PNG的第一帧。在您的情况下,您可以从APNG(或PNG,JPEG等)创建新图像,然后将其重新另存为PNG。如果使用 GD,它应该剥离动画数据,除非库已更新为支持 APNG。


推荐