PHP - 压缩图像以满足文件大小限制

nom*_*aam 1 php compression gd image php-gd

我必须上传满足最大宽度尺寸和最大文件大小的图像文件。

我有检查宽度大小并调整图像大小以满足最大图像宽度的代码。

但是,当我保存文件时,我可以设置质量

imagejpeg( $imgObject , 'resized/50.jpg' , 50 ); //save image and set quality
Run Code Online (Sandbox Code Playgroud)

我想做的是避免设置标准质量,因为提交的图像质量差异很大,并且一开始可能很低。

图像的质量应设置得尽可能高,且不超过最大文件大小限制。

我唯一的解决方案是以不同质量保存图像的多个版本,检查每个文件大小并选择最好的一个。这可行,但速度非常慢并且过程密集。

关于如何做得更好有什么建议吗?

谢谢

Bri*_*ams 6

这是实现这一目标的方法。在确定文件大小低于指定的最大值之前,它不会保存文件。

$original_file = 'original.jpg';
$resized_file = 'resized.jpg';
$max_file_size = '30000'; // maximum file size, in bytes

$original_image = imagecreatefromjpeg($original_file);

$image_quality = 100;

do {
    $temp_stream = fopen('php://temp', 'w+');
    $saved = imagejpeg($original_image, $temp_stream, $image_quality--);
    rewind($temp_stream);
    $fstat = fstat($temp_stream);
    fclose($temp_stream);

    $file_size = $fstat['size'];
}
while (($file_size > $max_file_size) && ($image_quality >= 0));

if (-1 == $image_quality) {
    echo "Unable to get the file that small. Best I could do was $file_size bytes at image quality 0.\n";
}
else {
    echo "Successfully resized $original_file to $file_size bytes using image quality $image_quality. Resized file saved as $resized_file.\n";
    imagejpeg($original_image, $resized_file, $image_quality + 1);
}
Run Code Online (Sandbox Code Playgroud)

在成功找到理想的压缩比之前,不需要写入任何文件。

此循环从 $image_quality 为 100 开始,然后向下计数,尝试临时内存缓冲区中的每个新值。如果尝试 0 但文件仍然太大,则会返回一条错误消息。否则,如果它达到有效的值,它会报告该值并使用该图像质量设置保存新文件。

如果您喜欢冒险,您可以实施二分搜索算法来更快地找到理想的压缩比,但这种快速修复会给出相同的结果,尽管可能会慢一点。