我目前遇到一些使用GD调整图像大小的问题.
一切正常,直到我想调整动画gif的大小,在黑色背景上提供第一帧.
我尝试过使用getimagesize但只给了我维度,没有什么可以区分任何gif和动画.
GIF动画不需要实际调整大小,只要能够跳过它们就足够了.
有线索吗?
PS.我无法访问imagemagick.
亲切的问候,
短剑的一种
Mar*_*els 38
在寻找同一问题的解决方案时,我注意到php.net网站对Davide和Kris所指的代码进行了跟进,但据作者称,内存密集程度较低,可能磁盘密集程度较低.
我会在这里复制它,因为它可能是有意义的.
来源:http://www.php.net/manual/en/function.imagecreatefromgif.php#88005
function is_ani($filename) {
if(!($fh = @fopen($filename, 'rb')))
return false;
$count = 0;
//an animated gif contains multiple "frames", with each frame having a
//header made up of:
// * a static 4-byte sequence (\x00\x21\xF9\x04)
// * 4 variable bytes
// * a static 2-byte sequence (\x00\x2C)
// We read through the file til we reach the end of the file, or we've found
// at least 2 frame headers
while(!feof($fh) && $count < 2) {
$chunk = fread($fh, 1024 * 100); //read 100kb at a time
$count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00[\x2C\x21]#s', $chunk, $matches);
}
fclose($fh);
return $count > 1;
}
Run Code Online (Sandbox Code Playgroud)
这是工作功能:
/**
* Thanks to ZeBadger for original example, and Davide Gualano for pointing me to it
* Original at http://it.php.net/manual/en/function.imagecreatefromgif.php#59787
**/
function is_animated_gif( $filename )
{
$raw = file_get_contents( $filename );
$offset = 0;
$frames = 0;
while ($frames < 2)
{
$where1 = strpos($raw, "\x00\x21\xF9\x04", $offset);
if ( $where1 === false )
{
break;
}
else
{
$offset = $where1 + 1;
$where2 = strpos( $raw, "\x00\x2C", $offset );
if ( $where2 === false )
{
break;
}
else
{
if ( $where1 + 8 == $where2 )
{
$frames ++;
}
$offset = $where2 + 1;
}
}
}
return $frames > 1;
}
Run Code Online (Sandbox Code Playgroud)
小智 5
这是对当前投票最高的答案的改进,但我还没有足够的声誉来发表评论。该答案的问题在于,它以 100Kb 块的形式读取文件,并且帧标记的结尾可能会被分成 2 个块。解决这个问题的方法是将前一帧的最后 20b 添加到下一帧:
<?php
function is_ani($filename) {
if(!($fh = @fopen($filename, 'rb')))
return false;
$count = 0;
//an animated gif contains multiple "frames", with each frame having a
//header made up of:
// * a static 4-byte sequence (\x00\x21\xF9\x04)
// * 4 variable bytes
// * a static 2-byte sequence (\x00\x2C) (some variants may use \x00\x21 ?)
// We read through the file til we reach the end of the file, or we've found
// at least 2 frame headers
$chunk = false;
while(!feof($fh) && $count < 2) {
//add the last 20 characters from the previous string, to make sure the searched pattern is not split.
$chunk = ($chunk ? substr($chunk, -20) : "") . fread($fh, 1024 * 100); //read 100kb at a time
$count += preg_match_all('#\x00\x21\xF9\x04.{4}\x00(\x2C|\x21)#s', $chunk, $matches);
}
fclose($fh);
return $count > 1;
}
Run Code Online (Sandbox Code Playgroud)