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


PHP - Compress Image to Meet File Size Limit

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

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

然而,当我保存文件时,我可以设置质量

imagejpeg( $imgObject , 'resized/50.jpg' , 50 ); //save image and set quality

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

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

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

有什么建议可以做得更好吗?

谢谢

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

$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);
}

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

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

如果你喜欢冒险,你可以实现一个二进制搜索算法来更快地找到理想的压缩比,但是这个快速修复给出了相同的结果,尽管可能有点慢。

No。

不幸的是,由于无法访问JPEG编码器的内部状态,因此无法估计最终文件大小。

你可以做的一件事是压缩图像的小版本,并从那里推断。将宽度和高度减少四倍意味着计算机只需要处理十六分之一的像素。这里的技巧是如何准备一个具有代表性的测试映像。使用imagecopyresampled()或imagecopyresize()缩放图像将不起作用。它对压缩特性的改变太大了。相反,你要做的是从原始图像复制每四个8x8的贴图:

$width1 = imagesx($img1);
$height1 = imagesy($img1);
$width2 = floor($width1 / 32) * 8;
$height2 = floor($height1 / 32) * 8;
$img2 = imagecreatetruecolor($width2, $height2);
for($x1 = 0, $x2 = 0; $x2 + 8 < $width2; $x1 += 32, $x2 += 8) {
    for($y1 = 0, $y2 = 0; $y2 + 8 < $height2; $y1 += 32, $y2 += 8) {
        imagecopy($img2, $img1, $x2, $y2, $x1, $y1, 8, 8);
    }
}

在不同的质量水平压缩较小的图像,并得到尊重的文件大小。将它们乘以16应该可以得到原始图像的一个相当好的估计。