Это сайт — моя персональная записная книжка. Интересна мне, по большей части, история, своя жизнь и немного программирование.

AVIF в GD

Вчера ночью чах, в очередной раз, над форматом AVIF — мысль была в качестве эксперимента добавить его в наш документооборот — продукт, разработкой которого я управляю.

Сейчас, чтобы показать документ в браузере, мы его конвертируем в JPEG — дёшево, сердито и везде поддерживается. Но страницы получаются большими (200 с лишком килобайт каждая) и иногда грузятся дольше, чем хотелось бы. Вот я и придумал проверить гипотезу, что AVIF тут поможет.

Пока примотал реализацию на соплях, как концепт. Результаты, кстати, хорошие, можно посмотреть на скриншоте разницу:

Разница в размере файлов в двух форматах — JPEG и AVIF

Но пока мотал, наткнулся на прекрасное. 🤦🏻‍♂️

В ПХП есть несколько модулей для работы с картинками, но самых распространённых два — GD и Imagick. Я начал с GD, так как на виртуалке он собран с поддержкой AVIF (а Imagick — нет), по крайней мере сам модуль так утверждает:

var_dump(gd_info()['AVIF Support']); // true
var_dump(imagetypes() & IMG_AVIF); // 256

Так же существует функция imageavif, что хороший знак — модуль устроен так, что если поддержки какого-то формата нет, то функция просто отсутствует.

Но при попытке сконвертировать картинку из JPEG в AVIF создавался файл нулевой длины, хотя функция возвращала true:

var_dump(imageavif(imagecreatefromjpeg('0.jpg'), '0.jpg.avif')); // true

GD это очень старый модуль, он родился, когда в PHP главенствовал процедурный модуль, поэтому его суть — функции; в PHP, если мы вызываем функции и что-то идёт не так, мы можем узнать что именно при помощи функции error_get_last. Помогла она и на этот раз:

array(4) {
  ["type"]=>
  int(2)
  ["message"]=>
  string(50) "imageavif(): AVIF image support has been disabled
"
  ["file"]=>
  string(17) "Command line code"
  ["line"]=>
  int(1)
}

Я погуглил ошибку, но не смог быстро разобраться что с ней сделать, поэтому переключился на Imagick. Там всё завелось без особых проблем — заменил шестую версию на седьмую и поставил недостающие пакеты:

yum shell
> remove php-pecl-imagick-im6
> install php-pecl-imagick-im7
> install ImageMagick7-heic
> install libheif
> run

В этом модуле, кстати, проверка на поддержку AVIF делается вот таким немного неочевидным способом:

$isAVIFSupported = Imagick::queryformats("AVIF") !== [];