Я пытаюсь объединить полосы PNG переменной длины в один GIF с использованием библиотек PHP GD и imagemagick.
Например:
= 4кадры
= 8 кадров
= 9 кадров
= 12 кадров
= 36 кадров
При объединении их в один 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");