我正在调整动画gif的大小并使用PHP中的imagick扩展名为其添加背景。
这是我正在使用的代码:
$image = new Imagick('myfile.gif');
$image = $image->coalesceimages();
$final = new \Imagick();
foreach ($image as $frame){
$frame->thumbnailImage($width, $height, true);
$geometry = $image->getImageGeometry();
$x = ( $width - $geometry['width'] ) / 2;
$y = ( $height - $geometry['height'] ) / 2;
$canvas = new \Imagick();
$canvas->newImage( $width, $height, $background);
$canvas->compositeImage( $image, \Imagick::COMPOSITE_OVER, $x, $y );
$final->addimage($canvas);
}
$final->desconstructimages();
$final->writeImages('resized.gif', true);
代码有效,调整后的图像也很完美。但是,在调整GIF动画大小时,需要一段时间。
使用上面的代码,大约需要10秒才能调整60k帧的36kb gif。对于非动画图像,大约需要半秒钟。
我正在ImageMagick 6.8.1-0 2012-12-20
上运行Ubuntu 12.10 32-bit
。
无论如何都要加快调整大小?
更新
我发现不需要在每一帧都调用thumbnailImage,所以现在我正在使用它:
$image = new Imagick('myfile.gif');
$image = $image->coalesceimages();
$final = new \Imagick();
$image->thumbnailImage($width, $height, true);
$geometry = $image->getImageGeometry();
$x = ( $width - $geometry['width'] ) / 2;
$y = ( $height - $geometry['height'] ) / 2;
foreach ($image as $frame){
$canvas = new \Imagick();
$canvas->newImage( $width, $height, $background);
$canvas->compositeImage( $image, \Imagick::COMPOSITE_OVER, $x, $y );
$final->addimage($canvas);
}
$final->desconstructimages();
$final->writeImages('resized.gif', true);
通过仅进行一次缩略图,我现在平均节省1秒(10%!)与之前相比!所以,对于那些说过的人,我应该对表现感到满意而不是抱怨,这证明你应该调查和改进你以前满意的事情,否则你将永远是一个平庸的开发者。
我当然是在尝试进一步减少转换时间,并且会进行一些分析以确定哪些调用最贵,然后针对这些调用。
答案 0 :(得分:2)
在花了一段时间尝试优化之后,我的平均时间大约为6.5秒,这比最初的10秒要好得多。
我现在正在调整循环外的动画并使用比optimizeImageLayers
更快的deconstructImages
,并且还会保留文件大小。
$image = new Imagick('myfile.gif');
$image = $image->coalesceimages();
$final = new \Imagick();
foreach ($image as $frame){
$image->thumbnailImage($width, $height, true);
$geometry = $image->getImageGeometry();
$x = ( $width - $geometry['width'] ) / 2;
$y = ( $height - $geometry['height'] ) / 2;
$canvas = new \Imagick();
$canvas->newImage( $width, $height, $background);
$canvas->compositeImage( $image, \Imagick::COMPOSITE_OVER, $x, $y );
$final->addimage($canvas);
}
$final = $final->optimizedImageLayers();
$final->writeImages('resized.gif', true);
目前我正在使用它并且对此非常满意。但是,一旦我找到一些空余时间,我将会考虑调整imagemagick的设置并使用颜色深度等来使其更好:)
答案 1 :(得分:1)
我知道这可能有点晚了但是对于像我这样的人来说,这里寻找一种方法来调整.gif的大小,这里写的是我编写的一些代码,它在图像中最多保留25帧(这个代码保持原始动画速度。)
$original = new \Imagick('/path/to/original/image');
$new = new \Imagick();
$i = 0;
$frameStep = ceil($original->getNumberImages() / 25);
foreach ($original as $frame) {
if ($i % $frameStep === 0) {
$delay = $frame->getImageDelay();
$frame->thumbnailImage($x, $y);
$frame->setImagePage($x, $y, 0, 0);
$frame->setImageDelay($delay * $frameStep);
$new->addImage($frame->getImage());
}
$i++;
}
file_put_contents('/path/to/NEW/file', $new->getImagesBlob());
$new->clear();
$new->destroy();
$original->clear();
$original->destroy();
答案 2 :(得分:-2)
如果60帧需要10秒钟来调整大小,那么每帧实际需要1/6秒,这甚至更好,你的结果为1帧,不是吗?当60多次工作需要更长时间时,你不应该抱怨。