Недавно я возился с форматом изображений WebP. Для этого я использую php 5.5.12 с установленной библиотекой gd (поддерживается gd 2.1.0 / webp). Я заметил, что по какой-то причине PHP создает испорченные webp-изображения. Код, который я использовал, следующий:
$im= imagecreatefromjpeg("test_img.jpg");
$succes = imagewebp($im, "test_img.webp");
if ($im !== false && $succes == true) {
echo "Succes.";
}
Я не могу понять, почему изображение webp, записанное в файловую систему этим php-скриптом, повреждено. Для вашего удобства я прикрепил одно из тестовых изображений. После обработки связанное с ним изображение webp действительно является поврежденным изображением в моей системе. Буду признателен за ваш вклад в это, так как я понятия не имею, почему это не работает должным образом.
Образ: http://i.stack.imgur.com/pwZHv.jpg (JPEG)
Некоторые версии libgd забывают добавить нулевое заполнение в конце файлов webp нечетного размера (эта ошибка, как уже упоминалось).
Это можно исправить с помощью PHP. Заменить это:
imagewebp($im);
С этим:
ob_start();
imagewebp($im);
if (ob_get_length() % 2 == 1) {
echo "\0";
}
ob_end_flush();
Или же, если вы хотите создать файл, а не выводить результат напрямую:
imagewebp($im, 'test_img.webp');
if (filesize('test_img.webp') % 2 == 1) {
file_put_contents('test_img.webp', "\0", FILE_APPEND);
}
Для тех из вас, кто сталкивался с теми же проблемами, что и я, вот ссылка на (в настоящее время) открытый багтрекер PHP, который, насколько мне известно, является источником проблемы. https://bugs.php.net/bug.php?id=66590
Грустно, действительно, это еще не исправлено, но мы можем решить это довольно элегантно сами. Для каждого кадра VP8, написанного imagewebp (), нам нужно проверить, четна ли длина кадра. Если это не так, мы добавляем нулевой байт в конец кадра и продолжаем. Обновление длины фрейма, определенной в его заголовке, не имеет значения, поскольку она уже имеет правильную длину — необходимые отступы просто никогда не добавлялись должным образом в сам файл.
Могу ли я предложить ImageMagick в качестве альтернативы?
$im = new Imagick('image.jpg');
$im->writeImage('image.webp');