编程

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

1178 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 函数,否则此更改不应导致任何向后兼容性问题。