关于php:不裁剪图片将jpgpnggif图片压缩到指定大小

4次阅读

共计 1318 个字符,预计需要花费 4 分钟才能阅读完成。

Boss 提了个需要,将图标压缩到 30kb 以内。前提是不扭转图片的宽高,只压缩体积。

这个需要对于 jpg/jpeg 这种有损压缩类型的图片来说就简略了。循环调用 GD 库 imagejpeg 函数设置图像品质。直到图片体积小于设定值。

针对于 png/gif 格局的图片就没那么简略了。对于这种格局的图片,目前都广泛采纳 GD 库的imagecopyresampled 函数将图像从新拷贝。能将体积缩小。这种形式有效性也只有一次,并不能满足需要。

官网的解释是:

imagecopyresampled() 将一幅图像中的一块正方形区域拷贝到另一个图像中,平滑地插入像素值,因而,尤其是,减小了图像的大小而依然放弃了极大的清晰度。

嗯,看了也没看懂。然而如同很厉害的样子 ……

so ~

转换图片类型:png -> jpg、gif -> jpg

再利用 imagejpeg 函数设置图片保留品质就解决了。当然了,如果是 gif 图片,那压缩后必定不能再动了

  /**
     * @param string $img_src 须要压缩的图像门路
     * @param string $save_src 压缩完后保留的图像门路
     * @param int $max_size_limit 图像大小限度 单位 kb
     * @return integer 压缩后图像大小 单位 kb
     * @throws \Throwable
     */
    public static function imgCompress(string $img_src, string $save_src, float $max_size_limit = 0)
    {if ($max_size_limit == 0) return 0;

        $file_size = intval(filesize($img_src) / 1024);
        if ($file_size <= $max_size_limit) return $file_size;

        $img_info = getimagesize($img_src);
        $type = image_type_to_extension($img_info[2], false);
        throw_if(!in_array($type, ['png', 'gif', 'jpg', 'jpeg']), ApiException::class, 1, '不反对的图片格式');

        // 创立新图像
        $img = ('imagecreatefrom' . $type)($img_src);
        $quality = 75; // 图像品质
        // 转换成 jpeg
        imagejpeg($img, $save_src, $quality);
        imagedestroy($img);
        while ($file_size > $max_size_limit) {$img = imagecreatefromjpeg($save_src);
            imagejpeg($img, $save_src, --$quality);
            imagedestroy($img);
            clearstatcache(true, $save_src); // 革除文件缓存
            $file_size = filesize($save_src) / 1024;
            if ($quality <= 1) break;
        }
        return intval(filesize($save_src) / 1024);
    }
正文完
 0