我正在尝试使用PHP GD和imagemagick库将可变长度的PNG条带组合到单个GIF中。
例如:
当将它们组合成一个GIF时,必须有足够的帧才能显示最长的动画,但是较短的动画则没有足够的帧。
现在,如果没有足够的帧,我只重复第一帧,但是正如您所期望的那样,这会导致动画停顿,直到它们全部重新开始:
帧数不是完全随机的,但是并不总是像示例中那样干净。有些组合有一对,每对25帧,最高36帧,有些则有1、3、4、9、5、12、16、26等帧。
希望这样做的原因是将所有条带组合成一个大图像,以展示一组条带(包含有关这些条带本身的信息)。
有没有办法解决我所思念的问题?还是我最好只是试着将条带加倍,直到它们都达到最高帧数,然后在这里和那里删除一些帧,希望没人注意?
这是显示我现在正在做什么的MCVE:
<?php
$pngStrips = [
"happy" => "https://i.stack.imgur.com/oq3Ex.png",
"shocked" => "https://i.stack.imgur.com/AeoEs.png",
"mk" => "https://i.stack.imgur.com/Ka6ho.png",
"dance" => "https://i.stack.imgur.com/lZan3.png",
"bored" => "https://i.stack.imgur.com/JiIN9.png"
];
$height = 130 * ceil(count($pngStrips) / 6);
$width = 150 * count($pngStrips);
// Set up the showase background gif (simplified to blank white for MCVE)
$background = imagecreatetruecolor($width, $height);
imagealphablending($background, true);
imagefill($background, 0, 0, imagecolorallocatealpha($background, 255, 255, 255, 0));
// Download from external source and split into frames and resize
$highestFrames = 0;
foreach($pngStrips as $name => $URL){
file_put_contents("./mcve/" . $name . ".png", file_get_contents($URL));
$dim = getimagesize("./mcve/" . $name . ".png");
exec("convert -crop " . $dim[1] . "x" . $dim[1] . " ./mcve/" . $name . ".png ./mcve/" . $name . "_frame_%02d.png");
exec("convert ./mcve/" . $name . "_frame_*.png -thumbnail 90x90^ -gravity center -extent 90x90 ./mcve/" . $name . "_frame_%02d_resized.png");
$frames = $dim[0] / $dim[1];
if($frames > $highestFrames) $highestFrames = $frames;
}
// Every frame of the main gif
for($i = 0; $i < $highestFrames; $i++ ){
$xcoord = 20;
$ycoord = 5;
$count = 1;
// Make a new frame
$frame = imagecrop($background, array('x'=>0,'y'=>0,'width'=>imagesx($background),'height'=>imagesy($background)));
// Add the appropriate frame to this frame of the main gif
foreach($pngStrips as $name => $URL) {
$frameFile = "./mcve/" . $name . "_frame_" . sprintf("%02d", $i) . "_resized.png";
if(!file_exists($frameFile)){
$frameFile = "./mcve/" . $name . "_frame_00_resized.png";
}
$powerImage = imagecreatefrompng($frameFile);
imagecopymerge($frame, $powerImage, $xcoord, $ycoord, 0, 0, 90, 90, 100);
$xcoord += 145;
if($count % 6 == 0){
$xcoord = 20;
$ycoord += 130;
}
$count++;
}
// Save frame
imagepng($frame, "./mcve/final_frame_" . sprintf("%02d", $i) . ".png");
}
// Into 1 big gif
exec("convert -loop 0 ./mcve/final_frame_*.png ./mcve/final.gif");
header('Content-Type: image/gif');
echo file_get_contents("./mcve/final.gif");
答案 0 :(得分:3)
最好的解决方案(但图像可能很大)是使用所有帧计数中的最低公倍数(在这种情况下为72,所以不是那么多),并根据需要重复每个图像序列多次(18 ,9,8,6,2)。