如何在PHP中优化VIPS性能

问题描述 投票:0回答:1

我想将以字符串形式保存在变量中的图像尽快转换为WebP格式,同时缩小较大的图像,但不放大较小的图像。基本系统是带有PHP 7.3的Debian 9.9。我尝试使用以下技术来测量速度:imagejpegimagewebp,使用cwepphp-vips。我使用了以下代码:

$jpeg = function() use ($image) {
    $old_image = @imagecreatefromstring($image);
    $old_width = (int)@imagesx($old_image);
    $old_height = (int)@imagesy($old_image);
    $new_width = 1920;
    $new_width = min($old_width, $new_width);
    $ratio = $new_width / $old_width;
    $new_height = $old_height * $ratio;
    $new_image = imagecreatetruecolor($new_width, $new_height);
    imagecopyresampled($new_image, $old_image, 0, 0, 0, 0, $new_width, $new_height, $old_width, $old_height);
    ob_start();
    imagejpeg($new_image, NULL, 75);
    $image = ob_get_clean();
};
$webp = function() use ($image) {
    $old_image = @imagecreatefromstring($image);
    $old_width = (int)@imagesx($old_image);
    $old_height = (int)@imagesy($old_image);
    $new_width = 1920;
    $new_width = min($old_width, $new_width);
    $ratio = $new_width / $old_width;
    $new_height = $old_height * $ratio;
    $new_image = imagecreatetruecolor($new_width, $new_height);
    imagecopyresampled($new_image, $old_image, 0, 0, 0, 0, $new_width, $new_height, $old_width, $old_height);
    ob_start();
    imagewebp($new_image, NULL, 75);
    $image = ob_get_clean();
};
$convert = function(string $image, int $width, int $height) {
    $cmd = sprintf('cwebp -m 0 -q 75 -resize %d %d -o - -- -', $width, $height);
    $fd = [
        0 => [ 'pipe', 'r' ], // stdin is a pipe that the child will read from
        1 => [ 'pipe', 'w' ], // stdout is a pipe that the child will write to
        2 => [ 'pipe', 'w' ], // stderr is a pipe that the child will write to
    ];
    $process = proc_open($cmd, $fd, $pipes, NULL, NULL);
    if (is_resource($process)) {
        fwrite($pipes[0], $image);
        fclose($pipes[0]);
        $webp = stream_get_contents($pipes[1]);
        fclose($pipes[1]);
        $result = proc_close($process);
        if ($result === 0 && strlen($webp)) {
            return $webp;
        }
    }
    return FALSE;
};
$cwebp = function() use ($image, $convert) {
    $old_image = @imagecreatefromstring($image);
    $old_width = (int)@imagesx($old_image);
    $old_height = (int)@imagesy($old_image);
    $new_width = 1920;
    $new_width = min($old_width, $new_width);
    $ratio = $new_width / $old_width;
    $new_height = $old_height * $ratio;
    $image = $convert($image, $new_width, $new_height);
};
$vips = function() use ($image) {
    $image = Vips\Image::newFromBuffer($image);
    $old_width = (int)$image->get('width');
    $old_height = (int)$image->get('height');
    $new_width = 1920;
    $new_width = min($old_width, $new_width);
    $ratio = $new_width / $old_width;
    // $new_height = $old_height * $ratio;
    $image = $image->resize($ratio);
    $image = $image->writeToBuffer('.webp[Q=75]');
};

我循环调用十次$jpeg()$webp()$cwebp()$vips(),以秒为单位的运行时间是:

JPEG: 0.65100622177124
WEBP: 1.4864070415497
CWEBP: 0.52562999725342
VIPS: 1.1211001873016

因此,调用cwebp CLI工具似乎是最快的方法,这令人惊讶。我已经多次阅读vips是一个极快的工具(通常比imagemagick快),所以我想重点关注vips

[有人可以帮助我优化$vips()以获得更好的性能吗?也许writeToBuffer()resize()有一些我不知道的选项。非常重要的是,所有操作都只能在内存中工作,而不要从磁盘读取文件或将文件存储在磁盘上。

php php-7 webp vips
1个回答
0
投票

正如@ADyson所说,最好在libvips跟踪器上询问:https://github.com/libvips/libvips/issues

对于速度,请不要使用resize,请使用thumbnail_buffer。它在单个操作中结合了打开和调整大小,因此可以利用诸如负载收缩之类的优势。根据图像的格式和大小,可以大大提高速度。

我还将检查您是否正在使用libjpeg-turbo。它比标准IJG libjpeg快3或4倍。

比较速度时,请记住调整大小。 php-vips默认使用lanczos3,这是一种非常高质量的调整大小。 cwebp使用的是更简单的方法。

检查输出文件的大小。在webp压缩过程中,您可以旋转许多旋钮,并且编码器可能未使用相同的设置。尤其要检查reduction-effort和无损/有损模式。

尝试(未试用):

$vips = function() use ($image) {
    $image = Vips\Image::thumbnail_buffer($image, 1920);
    $image = $image->writeToBuffer('.webp[Q=75]');
};
© www.soinside.com 2019 - 2024. All rights reserved.