编程

PHP 8.1: GD 库添加了 AVIF 图片支持

963 2023-04-23 18:50:00

AVIF (AV1 Image File) 是相对较新的图片格式,它支持多种特性比如透明度和 HDR。它是一种基于 AV1 视频格式的免版税图片格式,并且以较低的文件大小提供更高的压缩。

AVIF 图片格式最近才标准化,Chrome 85+ 和 FireFox 86+ 默认已经开始支持AVIF图片了。

PHP 8.1及更高版本的 GD 扩展支持 AVIF 图片格式,使之可以从 AVIF 中导入图片,或将图片导出为 AVIF。请注意,GD 扩展必须使用 AVIF 支持进行编译。它依赖于 libavif 软件包,在旧操作系统版本的默认存储库中可能找不到。

使用 AVIF 支持编译 GD

GD 扩展依赖于 libavif 软件包,以提供底层 AVIF 解码。GD 扩展要求 libavif 0.8.2 版本或者更高版本。

Ubuntu/Debian

apt install libavif-dev

RHEL/Fedora

dnf install libavif-devel

一旦安装了依赖项,就可以在 ./configure 脚本中,使用新的 --with-avif 标志用 AVIF 支持编译 PHP。

./buildconf --force
./configure --enable-gd --with-avif

请注意,上面的 ./configure 命令只是一个例子;对于生产系统,请确保启用其他扩展。

测试 AVIF 可用性

phpinfo()php -i CLI 命令可以揭示 AVIF 图像

php -i | grep AVIF
AVIF Support => enabled

也可以从 gd_info 函数中检索出 GD 特性。

gd_info();
[
     "GD Version" => "bundled (2.1.0 compatible)",
     "FreeType Support" => false,
     // ...
     "AVIF Support" => true,
]

此外,还有两个新函数,imagecreatefromavifimageavif,它们只有在 GD 扩展使用 AVIF 支持编译时可用。

if (function_exists('imageavif')) {
    // AVIF support available.
}

新的 AVIF 函数

PHP 8.1 中的 GD 扩展添加了两个新函数,如果该扩展是在AVIF支持下编译的。它们遵循了和其他 GD 函数(如imagecreatefromjpeg/imagejpeg, imagecreatefrompng/imagepng)相同的规范,

imagecreatefromavif 函数

function imagecreatefromavif(string $filename): GdImage|false {}

imagecreatefromavif 函数从给定的 AVIF 图片中返回一个新的 GdImage 实例。该 GdImage 实例可用用来来操作/转换图像。

imagecreatefromvif 函数类似于现有的函数,如 imagecreatefromjpegimagecreatefrompng,它们都会返回 GdImage,或者在失败时返回 false

imageavif 函数

/**
 * @param resource|string|null $file
 */
function imageavif(GdImage $image, $file = null, int $quality = -1, int $speed = -1): bool {}

imageavif 函数输出 AVIF 格式文件。

如果 $file 参数是 nullimageavif 函数打印二进制数据。如果提供了文件名(字符串),AVIF 图片会写入到该文件名下,或者如果给定的是文件资源,图片会被写入并关闭该资源。

int $qualityint $speed 可选参数被用于配置质量和速度值。

  • int $quality: 默认值 -1,重用 libavif 默认值。可接受的值在 0(质量最差)-100(质量最高)之间的整数。超出此范围的任何整数都会被固定在 0-100 范围内。
  • int $speed: 默认值 -1,重用 libavif 默认值 6。可接受的值在 0(最慢)-10(最快)之间的整数。超出此范围的任何整数都会被固定在 0-100 范围内。

默认值提供平衡的速度和质量。除非有特定原因,否则请尝试使用默认的 $speed$quality 值。

用例

将 JPEG 图片转换并保存为 AVIF

$image = imagecreatefromjpeg('image.jpeg');
imageavif($image, 'image.avif');

转换并保存 AVIF 图像为 PNG

$image = imagecreatefromavif('image.avif');
imagepng($image, 'image.png');

裁剪并以多种格式保存图片

$image = imagecreatefromjpeg('image.jpg');

$cropped_image = imagecrop($image, ['x' => 0, 'y' => 0, 'width' => 200, 'height' => 200]);

imagewebp($cropped_image, 'cropped.jpg');
imageavif($cropped_image, 'cropped.avif');

向后兼容性影响

新的 imagecreatefromaifimageavif 函数仅在 PHP 8.1+ 上可用,并且只有当 GD 扩展是使用 AVIF 支持构建的。它需要 libavif 版本 0.8.2 或更高版本。

Ubuntu 21.04 及以上、Debian 11及以上、Alpine 3.13 及以上、Fedora 34 是一些在默认软件库中提供 libavif-dev/libavif-devel 包的 Linux 发行版。

或者,可以直接从 AOMediaCodec/libavif 存储库中克隆源。

对于不能使用 GD 扩展或需要 PHP 8.1 的应用,同样支持 AVIF 的 Image Magick PECL 扩展可能是一个更可行的选项,具有更广泛的可用性。

$imagick = new Imagick();
$imagick->readImage('image.jpg');
$imagick->setImageFormat('avif');
$imagick->writeImage('image.avif');

除非应用程序声明了自己的 imagecreatefromvifimageavif 函数,否则此更改不应导致任何向后兼容性问题。