为了设法使用Imagick处理HEIC和WebP文件,我设法在服务器上安装了Imagemagick 7并设置了适当的PHP模块。
我可以轻松地将这些文件转换为PNG或JPEG等其他格式,而不会出现任何问题。
现在,我尝试将HEIC序列(original file)转换为GIF,但是结果并不完美。
首先,似乎Imagick无法确定每个图像之间的延迟。这样就产生了闪电般的快速动画。因此,到目前为止,我已经使用Imagick::setImageDelay对40个滴答声进行了硬编码。我不确定是否丢失了某些内容,或者Imagick / Imagemagick无法在HEIC序列上执行此操作。
我遇到的下一个问题是Imagick无法正确处理原始图像尺寸。为了解决这个问题,我必须获取原始图像的尺寸并在每帧上执行Imagick::cropImage和Imagick::thumbnailImage,然后再使用Imagick::setImagePage对其进行最终确定。
但是,我目前最大的问题是,结果的第一帧已损坏:
所以最终(破碎)结果如下:
(由heic2any生成的预期结果是:
我正在使用的(简体)代码:
<?php
if (!in_array('HEIC',\Imagick::queryFormats("HEI*"))) {
throw new \Exception('Unsupported format');
}
$sourceFile = __DIR__ . '/3.heic';
$targetFile = __DIR__ . '/3.gif';
if (!file_exists($sourceFile)) {
try {
$content = file_get_contents('https://github.com/alexcorvi/heic2any/blob/master/demo/' . basename($sourceFile) . '?raw=true');
if ($content === false) {
throw new \Exception('Unable to download source file.');
}
file_put_contents($sourceFile,$content);
} catch (\Exception $e) {
throw new \Exception('Unable to download source file: ' . $e->getMessage());
}
if (!file_exists($sourceFile)) {
throw new \Exception('Cannot find source file.');
}
}
$im = new \Imagick($sourceFile);
$width = $im->getImageWidth();
$height = $im->getImageHeight();
$im = $im->coalesceImages();
foreach ($im as $frame) {
$im->setImageDelay(40);
$frame->cropImage($width,$height,0);
$frame->thumbnailImage($width,$height);
$frame->setImagePage($width,0);
}
$im = $im->deconstructImages();
$im->writeImages($targetFile,true);
echo 'Size: ' . $width . 'x' . $height . '<br />Result:<br /><br /><img src="' . basename($targetFile) . '?v=' . time() . '" alt="" />';
所以我的问题是:
- 第一帧来自哪里?
- 如何避免呢?
- 是否有什么可以优化转换(代码)的?
更新:
还有另外一个.HEIC序列可与(click)一起使用,并且可以毫无问题地进行转换:
更新:
甚至cloudconvert之类的转换服务也无法正确处理图像并产生如下GIF动画: