我非常感激Sean Ja的回答。(他应该得到更多的赞。)然后我想让代码更易读和可配置(并支持透明gif上的文本并自动居中文本):
use Carbon\Carbon;
class CountdownGifHelper {
const DELAY = 100;
const MAX_FRAMES = 120;
public function addFrame($bgImg, $interval, $fontArr, &$frames, &$delays, $format) {
$image = imagecreatefrompng($bgImg);
$text = $interval->format($format);
ob_start();
imageSaveAlpha($image, true);
$backgroundColor = $fontArr['backgroundColor'];
imagefill($image, 0, 0, $backgroundColor);
imagecolortransparent($image, $backgroundColor);
$this->insertCenteredText($image, $fontArr, $text);
imagegif($image);
$frames[] = ob_get_contents();
ob_end_clean();
$delays[] = self::DELAY;
}
public function insertCenteredText(&$image, $fontArray, $text) {
$image_width = imagesx($image);
$image_height = imagesy($image);
$text_box = imagettfbbox($fontArray['size'], $fontArray['angle'], $fontArray['file'], $text);
$text_width = $text_box[2] - $text_box[0];
$text_height = $text_box[7] - $text_box[1];
$x = ($image_width / 2) - ($text_width / 2);
$y = ($image_height / 2) - ($text_height / 2);
imagettftext($image, $fontArray['size'], $fontArray['angle'], $x, $y, $fontArray['color'], $fontArray['file'], $text);
}
public function getAnimatedGif($timestamp, $bgImg, $fontArray) {
$future_date = Carbon::createFromTimestamp($timestamp);
$time_now = time();
$moment = new \DateTime(date('r', $time_now));
$frames = [];
$delays = [];
for ($i = 0; $i <= self::MAX_FRAMES; $i++) {
$interval = date_diff($future_date, $moment);
if ($future_date < $moment) {
$this->addFrame($bgImg, $interval, $fontArray, $frames, $delays, '00 : 00 : 00');
$loops = 1;
break;
} else {
$this->addFrame($bgImg, $interval, $fontArray, $frames, $delays, '%H : %I : %S');
$loops = 0;
}
$moment->modify('+1 second');
}
$animatedGif = new \App\Helpers\AnimatedGif($frames, $delays, $loops, 0, 0, 0);
return $animatedGif->getAnimation();
}
public function getFontArray($image) {
$fontArr = [
'file' => resource_path('assets/fonts/Kanit-Regular.ttf'),
'size' => 30,
'color' => imagecolorallocate($image, 90, 90, 90),
'backgroundColor' => imagecolorallocate($image, 0, 0, 0),
'angle' => 0,
];
return $fontArr;
}
}