将动画Gif合并到背景图像中

时间:2015-01-14 22:42:58

标签: php imagemagick imagick

我试图将动画gif合并为静态jpeg作为背景,这是由html画布和用户上传的文件上传生成的。我用imagemagick命令行很好地工作了

exec("convert ".$_paths['images_dir'].$fname.".gif  \( gif/cleared_dance".$dance.".gif -resize '80%' -repage 0x0-10+$imgHeight\! \) -coalesce -delete 0 -deconstruct -loop 0 ".$_paths['images_dir'].$fname.".gif");

这需要大约15秒来处理,这是可以接受的,但后来我发现我不能使用exec命令并且必须使用Imagick API,我最终能够使用以下代码重新创建该过程:

$data = $_POST["imgData"]; 
$dance = $_POST["dancer"]+1;
$spriteLeft = $_POST['left'];
$spriteTop = $_POST['top'];
$scale = $_POST['scale'];
$canvas = new Imagick();
$data = str_replace("data:image/png;base64,", "",$data); 
$data = base64_decode($data);
$canvas->readImageBlob($data);

$fname = 'tmp_'.uniqid();
$gif = new Imagick();
$gif->readImage('gif/cleared_dance'.$dance.'.gif');
do {
  $canvas->addImage($gif);
} while ($gif->nextImage());

foreach($canvas as $frame){
   if($frame->getIteratorIndex() != 0){
      $page = $frame->getImagePage();
      $frame->setImagePage(200,200,$page['x']+$spriteLeft,$page['y']+$spriteTop);
   }
}

这个代码大约需要5秒,这很好但是它们是gif中的空白帧,当它循环时非常烦人所以我在之后添加了这个:

$canvas->setIteratorIndex(0);
$canvas->removeImage();
$canvas = $canvas->deconstructImages();
$canvas->writeImages('tmp/'.$fname.'.gif', true);

这取出了空白帧,但增加了大约20-30秒的处理时间。我做错了什么,我已经按照代码的顺序和尝试不同的方法玩了很多。有没有办法像处理命令行那样将处理时间缩短到20秒以内?

1 个答案:

答案 0 :(得分:0)

你的代码很奇怪。为什么要将包含动画gif的Imagick对象的格式设置为JPG?你在合成图像后为什么要摆弄图像页

我很确定你希望你的代码看起来更像

$static = new Imagick();
//$static->readImage("./testFile.png");
$inputGif->readImageBlob($data);

$inputGif = new Imagick();
//$inputGif->readImage('./testGif.gif');
$inputGif->readImage('gif/cleared_dance'.$dance.'.gif');

$gifFrames = $inputGif->coalesceImages();

$outputGif = new Imagick();
$outputGif->setFormat('gif');

foreach ($gifFrames as $gifFrame) {
    $frame = clone $static;
    $frame->compositeimage(
        $gifFrame,
        Imagick::COMPOSITE_OVER,  // or maybe \Imagick::COMPOSITE_ATOP,
        0, 0 // Set the offset here if you don't want the gif in the top left corner.
    );

    $outputGif->addImage($frame);
}

$outputGif->setImageIterations(0); //loop forever
$outputGif->deconstructImages();
$outputGif->writeImages("./outso.gif", true);