Преобразуйте .HEI C последовательность в анимированный .GIF, используя Imagick - PullRequest
0 голосов
/ 13 апреля 2020

Мне удалось установить Imagemagick 7 на моем сервере и настроить соответствующий модуль PHP для работы с файлами HEI C и WebP с помощью Imagick.

Я могу конвертировать эти файлы легко в другие форматы, такие как PNG или JPEG, без проблем.

Теперь я пытаюсь преобразовать последовательность HEI C ( исходный файл ) в GIF, но результат не идеален.

Прежде всего, кажется, что Imagick не может определить задержку между каждым изображением. Это приводит к молниеносной анимации. Итак, на данный момент я жестко запрограммировал задержку в 40 тиков, используя Imagick :: setImageDelay . Я не уверен, что я что-то упустил или Imagick / Imagemagick не может сделать это на последовательностях HEI C.

Следующая проблема, с которой я столкнулся, заключается в том, что Imagick может неправильно обрабатывать размеры исходного изображения. Чтобы обойти это, я должен получить размеры исходного изображения и выполнить Imagick :: cropImage и Imagick :: thumbnailImage в каждом кадре, прежде чем завершить его с помощью Imagick: : setImagePage .

Тем не менее, моя самая большая проблема на данный момент заключается в том, что результат имеет поврежденный первый кадр:

broken first frame

Итак, окончательный (неработающий) результат выглядит следующим образом:

final broken result

В то время как ожидаемый результат (генерируемый heic2any ) равен :

heic2any result

(упрощенный) код, который я использую:

<?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, 0);
    $frame->thumbnailImage($width, $height);
    $frame->setImagePage($width, $height, 0, 0);
}

$im = $im->deconstructImages();
$im->writeImages($targetFile, true);

echo 'Size: ' . $width . 'x' . $height . '<br />Result:<br /><br /><img src="' . basename($targetFile) . '?v=' . time() . '" alt="" />';

Итак, мои вопросы:

  • Откуда берется 1-й кадр?
  • Как этого избежать?
  • Есть ли что-нибудь для оптимизации преобразования (кода)?

ОБНОВЛЕНИЕ:

Есть еще одна последовательность .HEI C, с которой можно поиграть ( click ), и эту можно без проблем преобразовать:

result

ОБНОВЛЕНИЕ:

Даже службы конвертирования, такие как cloudconvert , не могут правильно обрабатывать изображение и создавать GIF-анимацию, например:

whoops

...