GD库实现图片压缩

2021-08-03
class Image
{
    /**
     * @description: 
     * @var string 文件路径
     */
    public static $path;

    /**
     * @description: 
     * @var GdImage 图片资源
     */
    public static $img;
    
    /**
     * @description: 
     * @var array 图片宽高等数据
     */
    public static $imgInfo;
    
    /**
     * @description: 
     * @var string 图片格式
     */
    public static $imgCreatedType;

    /**
     * @description: 设置要压缩的图片
     * @param string $path 图片路径或图片流
     * @return {*}
     */
    public static function setImg($path)
    {
        self::$path = $path;
        if (!is_file($path)) {
            list($width, $height, $type) = getimagesizefromstring($path);
            self::$imgCreatedType = 'string';
        } else {
            list($width, $height, $type) = getimagesize($path);
            self::$imgCreatedType = image_type_to_extension($type, false);
        }
        if (!in_array(self::$imgCreatedType, ['gd', 'gd2', 'gif', 'jpeg', 'png', 'wbmp', 'webp', 'xbm', 'bmp'])) {
            throw new Exception('请上传正确的图片文件');
        }
        $imgCreateFunc = 'imagecreatefrom' . self::$imgCreatedType;
        self::$img = $imgCreateFunc($path);
        if (self::$img == false) {
            throw new Exception('图片文件不存在');
        }
        self::$imgInfo = array(
            'width'  => $width,
            'height' => $height
        );
    }
        
    /**
     * @description: 压缩图片
     * @param float $percent 缩小比例 0.1-1
     * @param bool $is_down 是否下载
     * @param bool $is_return 是否返回数据,如果为是则返回图片路径或资源
     * @param string $path 图片的保存路径,默认原路径
     * @param bool $is_cover 是否覆盖源文件
     * @return {*}
     */
    public static function thumb($percent = 0.7, $is_down = true, $is_return = false, $path = '', $is_cover = false)
    {
        if (!self::$img) {
            throw new Exception('请先设置要压缩的图片');
        }

        $new_width  = self::$imgInfo['width'] * $percent;
        $new_height = self::$imgInfo['height'] * $percent;

        $image_thump = imagecreatetruecolor($new_width, $new_height);
        imagecopyresampled($image_thump, self::$img, 0, 0, 0, 0, $new_width, $new_height, self::$imgInfo['width'], self::$imgInfo['height']);
        imagedestroy(self::$img);

        $imgSaveFunc = 'imagejpeg'; // 以jpg格式输出
        // $imgSaveFunc = 'image' . self::$imgCreatedType; // 以图片原格式输出

        if ($is_down) {
            if ($is_cover) {
                $file = self::$path;
            } else {
                if ($path) {
                    if (!is_dir($path))
                        mkdir($path, 0777, true);
                    $path = rtrim(str_replace('\\', '/', $path), '/') . '/';
                }
                $file = ($path ?: self::_getImgRawPath()) . self::_genImgName();
            }
            $imgSaveFunc($image_thump, $file);
            imagedestroy($image_thump);
            if ($is_return) {
                return $file;
            }
        } else {  
            if ($is_return) {
                ob_clean();
                ob_start();
                $imgSaveFunc($image_thump);
                $result = ob_get_contents();
                imagedestroy($image_thump);
                ob_end_clean();
                return $result;
            } else {
                ob_clean();
                header('content-type: image/jpeg');
                $imgSaveFunc($image_thump);
                imagedestroy($image_thump);
                flush();
            }
        }
    }

    /**
     * @description: 获取图片原路径
     * @param {*}
     * @return {*}
     */
    private static function _getImgRawPath()
    {
        return str_replace('\\', '/', pathinfo(self::$path, PATHINFO_DIRNAME)) . '/';
    }

    /**
     * @description: 获取新文件名
     * @param {*}
     * @return {*}
     */
    private static function _genImgName()
    {
        $name = str_replace('.', '', uniqid('', true));
        return $name . '.jpg';
        // return $name . '.' . (self::$imgCreatedType == 'string' ? pathinfo(self::$path, PATHINFO_EXTENSION) : self::$imgCreatedType);
    }

    /**
     * @description: 压缩目录下的图片
     * @param string $path 图片路径
     * @param string $to_path 压缩后保存的路径,默认原路径
     * @param float $percent 压缩比例
     * @param bool $is_recur 是否递归
     * @param bool $is_cover 是否覆盖源文件
     * @return {*}
     */
    public static function dirThumb($path, $to_path = '', $percent = 0.7, $is_recur = false, $is_cover = false)
    {
        if (!is_dir($path)) {
            throw new Exception('目录不存在');
        }
        $path    = rtrim(str_replace('\\', '/', $path), '/') . '/';
        if ($to_path) {
            $to_path = rtrim(str_replace('\\', '/', $to_path), '/') . '/';
        }
        
        $dir  = opendir($path);
        while ($file = readdir($dir)) {
            if ($file != '.' && $file != '..') {
                $new_file = $path . $file;
                var_dump($new_file);
                if (is_dir($new_file)) {
                    if ($is_recur)
                        self::dirThumb($new_file, ($to_path ?: $path). $file, $percent, $is_cover);
                } else {
                    try {
                        self::setImg($new_file);
                        self::thumb($percent, true, false, $to_path, $is_cover);
                    } catch (\Exception $e) {

                    }
                }
            }
        }
    }

    /**
     * @description: 批量压缩
     * @param array $imgArray 要压缩的图片数组
     * @param string $to_path 压缩后保存的路径,默认原路径
     * @param float $percent 压缩比例
     * @param bool $is_return 是否返回压缩后保存的路径
     * @param bool $is_cover 是否覆盖源文件
     * @return {*}
     */
    public static function batchThumb($imgArray, $to_path = '', $percent = 0.7, $is_return = false, $is_cover = false)
    {
        $result = [];
        foreach ($imgArray as $img) {
            try {
                self::setImg($img);
                $result[] = self::thumb($percent, true, $is_return, $to_path, $is_cover);
            } catch (\Exception $e) {

            }  
        }
        return $result;
    }
}

// 示例
$path = 'C:\Users\Administrator\Desktop\16051538351171.jpg';
Image::setImg($path);
Image::thumb();

 

{/if}