PHP Imagick使每次更改特定二进制文件的PNG文件 - 从相同的图像文件
我有一个PNG文件问题。PHP Imagick使每次更改特定二进制文件的PNG文件 - 从相同的图像文件
当我使用PHP Imagick库转换图像时,每次都会得到不同的二进制集,尽管我多次尝试使用相同的图像文件。
当我比较这两个文件时,结果表明它只有几个字节是不同的,而其余的字节完全相同,并且这些字节偏移也都是时间相同的。
我真的不知道怎么来的这些字节可能是所有的时间不同(好像它存储时间戳或还有什么呢?)
这里是高燃点二进制PNG文件的二进制,有人帮助我要弄清楚究竟发生了什么这个二进制文件:
我还附上了PNG文件:
谢谢。
PNG文件被“分块”,这意味着它们具有不同的命名部分来定义不同的数据。在PNG file format specification中,您可以在PNG文件中找到关于tIME
块的信息。
时间块给出了最后一次图像修改的时间(不是初始图像创建时的 时间)。
另一件要注意的规范是,第一个字母是小写(t
),这意味着该块不是必需的。所以,彻底删除它应该可以解决你的问题。
我没有使用Imagick,但通过PHP documentation,它看起来像它提供了一种方法来从创建的PNG文件中删除tIME
块。 0123'方法可让您更好地控制Imagick对图像所做的操作(list of available options)。 png:exclude-chunk
选项可能是你正在寻找的。
此代码未经测试,因为我目前无法使用Imagick库访问服务器。
$im = new Imagick();
$im->setOption('png:exclude-chunk', 'tIME'); // comma separated list of chunks
非常感谢您提供2种解决方案,我为他们两个都赞不绝口,并且接受这一点,因为这样做很好! – Codemole
这很可能是由于图片的元数据?即文件被修改时的时间戳?
看着突出显示的行之前的行,我可以看到tIME在那里,所以它似乎是这种情况。
如果你正试图从那些已经被创建,或者如果你没有访问Imagick库图像删除tIME
块,我测试了一些代码,可以从小型十岁上下的* PNG删除块文件。
PNG文件具有specific format:
- PNG签名[8个字节]
- 块数据 - 与IHDR开始并以IEND块在它们之间的其它的块结束。每个块具有以下:
- 长度[4个字节]
- 类型[4个字节]
- 数据[长度字节](可能是空的,如果长度为0)
- CRC(循环冗余码) [4个字节]
利用这些信息,我们就可以通过块逐一念给我们找到要删除的一个。
// read the PNG file's contents into a string
$str = file_get_contents('hD0aZ.png');
// how far into the string we are currently
$offset = 0;
// offset for the PNG signature (8 bytes)
$offset += 8;
// what we will replace in the original string once it is found
$timechunk = '';
while($offset < strlen($str)){
// get the current chunk information
list($length,$chunk,$name) = readchunk(substr($str,$offset));
if($name == 'tIME'){
$timechunk = $chunk;
break;
}
// move to the next chunk
$offset += $length;
}
header("Content-Type:image/png");
print str_replace($timechunk,'',$str);
function readchunk($str){
$length = hexdec(bin2hex(substr($str,0,4)));
// 4 bytes for length, 4 bytes for chunk name, 4 bytes for CRC = 12 bytes
return array(
12+$length, // total length of chunk
substr($str,0,12+$length), // full chunk data
substr($str,4,4) // chunk name
);
}
*如果您的PNG文件过大,tIME
块不够早在字符串中,你可能最终与问题,如果你的$offset
尝试走了过来PHP_INT_MAX
。但是,我可以让这段代码处理你在问题中提供的图像。
在上面一行中,您突出显示的是'tIME'块的开始,这应该是最后一次修改时间([请参阅此处的规格](https://www.w3.org/TR/PNG/# 11tIME))。你也可以找到[这个Unix SE问题](https://unix.stackexchange.com/questions/255252/create-the-same-png-with-imagemagick-2-times-binaries-differ)有帮助。 –
@JoshH为什么只在Linux操作系统中添加?那么,如何使用Imagick(PHP)保存PNG时如何排除此块? – Codemole
由于不同的字节每次都处于已知的偏移量,因此可以选择添加后处理步骤来清零这些字节? – GeorgeQ