简介
php-vips 是 libvips 8.7 及后续版本的 PHP 绑定,支持 PHP 7.4 及以上版本。
libvips 非常快且内存占用极低。vips-php-bench 仓库将 php-vips 与 imagick 和 gd 进行测试。在笔记本电脑上测试结果显示,php-vips 比 imagick 快约 4 倍,内存占用仅为后者的 1/10。
使用 libvips 的程序不会直接操作图像,而是从源图像开始构建图像处理操作管道。当管道连接到目标时,整个管道会一次性并行执行,并以小片段流的形式从源图像传输到目标图像。
安装
你需要先安装 libvips 库。它在 Linux 包管理器、Homebrew 和 MacPorts 中都有,在 vips 官网提供 Windows 二进制文件。例如,在 Debian 上:
sudo apt-get install --no-install-recommends libvips42
(--no-install-recommends 可防止 Debian 安装大量额外包)
或者在 macOS 上:
brew install vips
你需要在 PHP 中启用 FFI(请参阅 PHP FFI 配置),然后将 vips 添加到你的 composer.json 中:
"require": {"jcupitt/vips": "2.4.0"}
php-vips 目前不支持预加载,因此你需要在全局启用 FFI。这存在一些安全隐患,因为你的服务器上运行 PHP 的任何人都可以调用他们有权访问的任何本机库。
当然,如果攻击者已经在你的 Web 服务器上运行自己的 PHP 代码,你很可能已经中招了,不幸的是……
最后,在 PHP 8.3 及以上版本,你需要禁用栈溢出测试。php-vips 在主线程之外执行 FFI 回调,这会混淆这些检查(至少在 PHP 8.3.0 中)。
在你的 php.ini 中添加:
zend.max_allowed_stack_size=-1
示例
#!/usr/bin/env php<?phprequire __DIR__ . '/vendor/autoload.php';use Jcupitt\Vips;// Windows 快捷方式Vips\FFI::addLibraryPath("C:/vips-dev-8.16/bin");// 检查 libvips 版本echo 'libvips version: ' . Vips\Config::version() . PHP_EOL;// 快速缩略图生成器$image = Vips\Image::thumbnail('somefile.jpg', 128);$image->writeToFile('tiny.jpg');// 加载图像、获取字段、处理、保存$image = Vips\Image::newFromFile($argv[1]);echo "width = $image->width\n";$image = $image->invert();$image->writeToFile($argv[2]);
运行方式:
$ composer install$ ./try1.php ~/pics/k2.jpg x.tif
请查看 examples/。我们有完整的格式化 API 文档。
工作原理
php-vips 使用 php-ffi 直接调用 libvips 二进制文件。它会内省库二进制文件,并将找到的方法作为 Image 类中的成员呈现。
这意味着你看到的 API 取决于 php-vips 在运行时找到的 libvips 版本,而不是取决于 php-vips 本身。php-vips 文档假设你使用的是最新稳定的 libvips 库版本。
之前的 php-vips 版本依赖二进制扩展而不是 php-ffi,在 1.x 分支 仍然可用并受支持。
API 介绍
几乎所有方法都会返回一个新图像作为结果,因此你可以链式调用。例如:
$new_image = $image->more(12)->ifthenelse(255, $image);
会生成大于 12 的像素掩码,然后使用该掩码将像素设置为 255 或原始图像。
注意,libvips 操作始终创建新图像,它们不会修改现有图像,因此在上面一行之后,$image 保持不变。
你可以将 long、double、array 和 image 作为参数。例如:
$image = $image->add(2);
将 2 添加到每个波段元素,或者:
$image = $image->add([1, 2, 3]);
将 1 添加到第一个波段,2 添加到第二个,3 添加到第三个。或者:
$image = $image->add($image2);
添加两个图像。或者:
$image = $image->add([[1, 2, 3], [4, 5, 6]]);
从数组创建一个 3x2 图像,然后将其添加到原始图像。
几乎所有方法都可以接受额外的最终参数:一个选项数组。例如:
$image->writeToFile("fred.jpg", ["Q" => 90]);
php-vips 附带 API 文档。要从源代码重新生成这些文档,请运行:
$ vendor/bin/phpdoc
不幸的是,由于 php-doc 限制,这些文档不会列出每个操作的所有选项。要获取完整 API 描述,你需要查看主 libvips 文档:
https://libvips.org/API/current
测试和安装
$ composer install$ composer test$ vendor/bin/phpdoc