PHP封装图片处理类(缩放、裁剪、水印)

1、创建ImageHandler类和三个主要方法

class ImageHandler{
    //图片后缀对应的处理函数:GD库
    private static $ext = array(
        'jpg' => 'jpeg',
        'jpeg' => 'jpeg',
        'png' => 'png',
        'gif' => 'gif'
    );
    //记录错误信息
    public static $error;
    //制作缩略图
    public static function thumb(){}
    // 图片裁剪
    public static function crop(){}
    // 单个图片水印添加
    public static function watermark(){}
}

2、新增检测方法

由于三个方法都需要传入文件名和路径,需要进行有效性检测,所以新增两个检测方法

    /**
     * @desc 检测文件有效性
     * @param $file,文件名
     * @return bool
     */
    public static function checkFile(&$file){
        //字符串处理
        $file = trim($file);
        //判定资源有效性
        if (!is_file($file)) {
            self::$error = "图片{$file}不存在!";
            return false;
        }
        //获取文件信息:判定是否可以处理文件
        $file_info = pathinfo($file);
        if (!array_key_exists($file_info['extension'], self::$ext)) {
            self::$error = "系统无法处理图片{$file}的类型!";
            return false;
        }
        return true;
    }
    /**
     * @desc 检测路径有效性
     * @param $path,文件名
     * @return bool
     */
    public static function checkPath(&$path){
        //字符串处理
        $path = rtrim(trim($path), '/'). '/';
        if (!is_dir($path)) {
            self::$error = "{$path}存储路径不存在!";
            return false;
        }
        return true;
    }

3、实现图片缩放方法

图片缩放使用的是等比例缩放的方法,分为固定宽高、只固定宽度和只固定高度三种类型,由于只用一个函数实现,所以使用数组传参的方式

    /**
     * @desc 制作缩略图
     * @param array $info,关联数组参数,应该包含以下元素:
     * string file => 缩略图存储路径
     * string path => 缩略图存储路径
     * int width => 缩略图宽
     * int height => 缩略图高
     * @return bool|string,返回缩略图文件名,错误返回false
     */
    public static function thumb($info){
        $file = $info['file'];
        $path = $info['path'];

        if(!self::checkFile($file)) return false;
        if(!self::checkPath($path)) return false;
        $file_info = pathinfo($file);
        $file_ext = $file_info['extension'];    //文件扩展名
        $img_info = getimagesize($file);

        //根据文件扩展名确定原图资源函数:打开函数和保存函数
        $open = 'imagecreatefrom' . self::$ext[$file_ext];
        $save = 'image' . self::$ext[$file_ext];
        //打开图片资源
        $src = $open($file);

        if(isset($info['width']) && isset($info['height'])){
            //固定宽高,背景补白
            $width = $info['width'];
            $height = $info['height'];
            //补白计算:计算宽高比
            $src_b = $img_info[0] / $img_info[1];
            $thumb_b = $width / $height;
            //原图宽高比大于缩略图:原图太宽,缩略图的宽度要占满
            if ($src_b > $thumb_b) {
                //缩略图实际宽高
                $w = $width;
                $h = ceil($width / $src_b);
                //缩略图起始位置
                $x = 0;
                $y = ceil(($height - $h) / 2);
            } else {
                //原图宽高比小于缩略图:原图太高,缩略图的高度要占满
                $w = ceil($src_b * $width);
                $h = $height;
                $x = ceil(($width - $w) / 2);
                $y = 0;
            }

        }else if(isset($info['width']) && !isset($info['height'])){
            //固定宽度
            $width = $info['width'];
            //计算缩略图高度
            $src_b = $img_info[0] / $img_info[1];
            $height = $width / $src_b;
            $x = 0;
            $y = 0;
            $w = $width;
            $h = $height;
        }else if(!isset($info['width']) && isset($info['height'])){
            //固定高度
            $height = $info['height'];
            //计算缩略图宽度
            $src_b = $img_info[0] / $img_info[1];
            $width = $height * $src_b;
            $x = 0;
            $y = 0;
            $w = $width;
            $h = $height;
        }else{
            self::$error = '必须给出缩略图宽度或高度!';
            return false;
        }
        $thumb = imagecreatetruecolor($width, $height);
        //背景补白
        $bg_color = imagecolorallocate($thumb, 255, 255, 255);
        imagefill($thumb, 0, 0, $bg_color);

        //复制合并:缩略图
        if (!imagecopyresampled($thumb, $src, $x, $y, 0, 0, $w, $h, $img_info[0], $img_info[1])) {
            //采样复制失败
            self::$error = '缩略图制作失败!';
            return false;
        }
        //保存图片
        $res = $save($thumb, $path . 'thumb_' . $file_info['basename']);
        //销毁资源
        imagedestroy($src);
        imagedestroy($thumb);
        if ($res) {     //保存成功
            return 'thumb_' . $file_info['basename'];
        } else {        //保存失败
            self::$error = '图片保存失败!';
            return false;
        }
    }    

4、实现图片裁剪方法

 

/**
     * @desc 图片裁剪
     * @param $file,源文件名
     * @param $path,裁剪图存储路径
     * @param int $width = 60,裁剪图宽
     * @param int $height = 60,裁剪图高
     * @param int $src_x = 0,原图裁剪始点x坐标
     * @param int $src_y = 0,原图裁剪始点y坐标
     * @return bool|string,返回裁剪图文件名,错误返回false
     */
    public static function crop($file, $path, $width = 60, $height = 60, $src_x = 0, $src_y = 0){
        if(!self::checkFile($file)) return false;
        if(!self::checkPath($path)) return false;

        $file_info = pathinfo($file);
        $file_ext = $file_info['extension'];    //文件扩展名
        $img_info = getimagesize($file);

        if($src_x + $width > $img_info[0] || $src_y + $height >  $img_info[1]){
            self::$error = '图片区域选择越界!';
            return false;
        }

        //根据文件扩展名确定原图资源函数:打开函数和保存函数
        $open = 'imagecreatefrom' . self::$ext[$file_ext];
        $save = 'image' . self::$ext[$file_ext];
        //打开图片资源
        $src = $open($file);
        $crop = imagecreatetruecolor($width, $height);

        if (!imagecopyresampled($crop, $src, 0, 0, $src_x, $src_y, $width, $height, $width, $height)){
            self::$error = '裁剪失败!';
            return false;
        }
        //保存图片
        $res = $save($crop, $path . 'corp_' . $file_info['basename']);
        //销毁资源
        imagedestroy($src);
        imagedestroy($crop);
        if ($res) {     //保存成功
            return 'corp_' . $file_info['basename'];
        } else {        //保存失败
            self::$error = '图片保存失败!';
            return false;
        }
    }

5、实现图片添加单个水印方法

    /**
     * @desc 单个图片水印添加
     * @param $dst_file,目标图片文件名
     * @param $src_file,水印图片文件名
     * @param $path,添加水印的图片存储路径
     * @param int $dst_x,水印在目标图片的始点x坐标
     * @param int $dst_y,水印在目标图片的始点y坐标
     * @return bool|string,返回添加水印图文件名,错误返回false
     */
    public static function watermark($dst_file, $src_file, $path, $dst_x = 0, $dst_y = 0){
        if(!self::checkFile($dst_file)) return false;
        if(!self::checkFile($src_file)) return false;
        if(!self::checkPath($path)) return false;
        $src_file_info = pathinfo($src_file);
        $dst_file_info = pathinfo($dst_file);
        $src_file_ext = $src_file_info['extension'];
        $dst_file_ext = $dst_file_info['extension'];
        $open_src = 'imagecreatefrom' . self::$ext[$src_file_ext];
        $open_dst = 'imagecreatefrom' . self::$ext[$dst_file_ext];
        $save_dst = 'image' . self::$ext[$dst_file_ext];
        $src = $open_src($src_file);
        $dst = $open_dst($dst_file);
        if(imagesx($src) > imagesx($dst) || imagesy($src) > imagesy($dst) ){
            self::$error = '水印过大!';
            return false;
        }
        if(!imagecopy($dst,$src,$dst_x,$dst_y,0,0,imagesx($src),imagesy($src))){
            self::$error = '水印添加失败!';
            return false;
        }
        $res = $save_dst($dst, $path . 'watermark_' . $dst_file_info['basename']);
        imagedestroy($src);
        imagedestroy($dst);
        if ($res) {     
            return 'watermark_' . $dst_file_info['basename'];
        } else {      
            self::$error = '图片保存失败!';
            return false;
        }
    }

6、测试

测试准备:一个较大图片1.jpg、一个较小图片wechat.png作为水印图片

$file1 = '1.jpg';
$path11 = 'thumb/';
$path12 = 'thumb_width/';
$path13 = 'thumb_height/';
$width1 = 400;
$height1 = 240;
//测试固定宽高式缩放
$res = ImageHandler::thumb(array(
    'file' => $file1,
    'path' => $path11,
    'width' => $width1,
    'height' => $height1,
));
if(!$res){
    die(ImageHandler::$error);
}
echo "固定宽高式缩放图片保存成功:thumb/{$res}<br>";
//测试固定宽度式缩放
$res = ImageHandler::thumb(array(
    'file' => $file1,
    'path' => $path12,
    'width' => $width1,
));
if(!$res){
    die(ImageHandler::$error);
}
echo "固定宽度式缩放图片保存成功:thumb_width/{$res}<br>";
//测试固定高度式缩放
$res = ImageHandler::thumb(array(
    'file' => $file1,
    'path' => $path13,
    'height' => $height1,
));
if(!$res){
    die(ImageHandler::$error);
}
echo "固定高度式缩放图片保存成功:thumb_height/{$res}<br>";
//测试图片裁剪
$res = ImageHandler::crop(' 1.jpg  ', ' crop/  ', 400, 400, 600, 200);
if(!$res){
    die(ImageHandler::$error);
}
echo "裁剪图片保存成功:crop/{$res}<br>";
//测试图片水印
$res = ImageHandler::watermark('1.jpg', '  wechat.png', 'watermark/');
if(!$res){
    die(ImageHandler::$error);
}
echo "水印图片保存成功:watermark/{$res}<br>";

7、附完整代码

<?php

//图片处理类
namespace vendor;

class ImageHandler{
    //图片后缀对应的处理函数:GD库
    private static $ext = array(
        'jpg' => 'jpeg',
        'jpeg' => 'jpeg',
        'png' => 'png',
        'gif' => 'gif'
    );
    //记录错误信息
    public static $error;

    /**
     * @desc 检测文件有效性
     * @param $file,文件名
     * @return bool
     */
    public static function checkFile(&$file){
        //字符串处理
        $file = trim($file);
        //判定资源有效性
        if (!is_file($file)) {
            self::$error = "图片{$file}不存在!";
            return false;
        }
        //获取文件信息:判定是否可以处理文件
        $file_info = pathinfo($file);
        if (!array_key_exists($file_info['extension'], self::$ext)) {
            self::$error = "系统无法处理图片{$file}的类型!";
            return false;
        }
        return true;
    }
    /**
     * @desc 检测路径有效性
     * @param $path,文件名
     * @return bool
     */
    public static function checkPath(&$path){
        //字符串处理
        $path = rtrim(trim($path), '/'). '/';
        if (!is_dir($path)) {
            self::$error = "{$path}存储路径不存在!";
            return false;
        }
        return true;
    }
    /**
     * @desc 制作缩略图
     * @param array $info,关联数组参数,应该包含以下元素:
     * string file => 缩略图存储路径
     * string path => 缩略图存储路径
     * int width => 缩略图宽
     * int height => 缩略图高
     * @return bool|string,返回缩略图文件名,错误返回false
     */
    public static function thumb($info){
        $file = $info['file'];
        $path = $info['path'];

        if(!self::checkFile($file)) return false;
        if(!self::checkPath($path)) return false;
        $file_info = pathinfo($file);
        $file_ext = $file_info['extension'];    //文件扩展名
        $img_info = getimagesize($file);

        //根据文件扩展名确定原图资源函数:打开函数和保存函数
        $open = 'imagecreatefrom' . self::$ext[$file_ext];
        $save = 'image' . self::$ext[$file_ext];
        //打开图片资源
        $src = $open($file);

        if(isset($info['width']) && isset($info['height'])){
            //固定宽高,背景补白
            $width = $info['width'];
            $height = $info['height'];
            //补白计算:计算宽高比
            $src_b = $img_info[0] / $img_info[1];
            $thumb_b = $width / $height;
            //原图宽高比大于缩略图:原图太宽,缩略图的宽度要占满
            if ($src_b > $thumb_b) {
                //缩略图实际宽高
                $w = $width;
                $h = ceil($width / $src_b);
                //缩略图起始位置
                $x = 0;
                $y = ceil(($height - $h) / 2);
            } else {
                //原图宽高比小于缩略图:原图太高,缩略图的高度要占满
                $w = ceil($src_b * $width);
                $h = $height;
                $x = ceil(($width - $w) / 2);
                $y = 0;
            }

        }else if(isset($info['width']) && !isset($info['height'])){
            //固定宽度
            $width = $info['width'];
            //计算缩略图高度
            $src_b = $img_info[0] / $img_info[1];
            $height = $width / $src_b;
            $x = 0;
            $y = 0;
            $w = $width;
            $h = $height;
        }else if(!isset($info['width']) && isset($info['height'])){
            //固定高度
            $height = $info['height'];
            //计算缩略图宽度
            $src_b = $img_info[0] / $img_info[1];
            $width = $height * $src_b;
            $x = 0;
            $y = 0;
            $w = $width;
            $h = $height;
        }else{
            self::$error = '必须给出缩略图宽度或高度!';
            return false;
        }
        $thumb = imagecreatetruecolor($width, $height);
        //背景补白
        $bg_color = imagecolorallocate($thumb, 255, 255, 255);
        imagefill($thumb, 0, 0, $bg_color);

        //复制合并:缩略图
        if (!imagecopyresampled($thumb, $src, $x, $y, 0, 0, $w, $h, $img_info[0], $img_info[1])) {
            //采样复制失败
            self::$error = '缩略图制作失败!';
            return false;
        }
        //保存图片
        $res = $save($thumb, $path . 'thumb_' . $file_info['basename']);
        //销毁资源
        imagedestroy($src);
        imagedestroy($thumb);
        if ($res) {     //保存成功
            return 'thumb_' . $file_info['basename'];
        } else {        //保存失败
            self::$error = '图片保存失败!';
            return false;
        }
    }

    /**
     * @desc 图片裁剪
     * @param $file,源文件名
     * @param $path,裁剪图存储路径
     * @param int $width = 60,裁剪图宽
     * @param int $height = 60,裁剪图高
     * @param int $src_x = 0,原图裁剪始点x坐标
     * @param int $src_y = 0,原图裁剪始点y坐标
     * @return bool|string,返回裁剪图文件名,错误返回false
     */
    public static function crop($file, $path, $width = 60, $height = 60, $src_x = 0, $src_y = 0){
        if(!self::checkFile($file)) return false;
        if(!self::checkPath($path)) return false;

        $file_info = pathinfo($file);
        $file_ext = $file_info['extension'];    //文件扩展名
        $img_info = getimagesize($file);

        if($src_x + $width > $img_info[0] || $src_y + $height >  $img_info[1]){
            self::$error = '图片区域选择越界!';
            return false;
        }

        //根据文件扩展名确定原图资源函数:打开函数和保存函数
        $open = 'imagecreatefrom' . self::$ext[$file_ext];
        $save = 'image' . self::$ext[$file_ext];
        //打开图片资源
        $src = $open($file);
        $crop = imagecreatetruecolor($width, $height);

        if (!imagecopyresampled($crop, $src, 0, 0, $src_x, $src_y, $width, $height, $width, $height)){
            self::$error = '裁剪失败!';
            return false;
        }
        //保存图片
        $res = $save($crop, $path . 'corp_' . $file_info['basename']);
        //销毁资源
        imagedestroy($src);
        imagedestroy($crop);
        if ($res) {     //保存成功
            return 'corp_' . $file_info['basename'];
        } else {        //保存失败
            self::$error = '图片保存失败!';
            return false;
        }
    }

    /**
     * @desc 单个图片水印添加
     * @param $dst_file,目标图片文件名
     * @param $src_file,水印图片文件名
     * @param $path,添加水印的图片存储路径
     * @param int $dst_x,水印在目标图片的始点x坐标
     * @param int $dst_y,水印在目标图片的始点y坐标
     * @return bool|string,返回添加水印图文件名,错误返回false
     */
    public static function watermark($dst_file, $src_file, $path, $dst_x = 0, $dst_y = 0){
        if(!self::checkFile($dst_file)) return false;
        if(!self::checkFile($src_file)) return false;
        if(!self::checkPath($path)) return false;
        $src_file_info = pathinfo($src_file);
        $dst_file_info = pathinfo($dst_file);
        $src_file_ext = $src_file_info['extension'];
        $dst_file_ext = $dst_file_info['extension'];
        $open_src = 'imagecreatefrom' . self::$ext[$src_file_ext];
        $open_dst = 'imagecreatefrom' . self::$ext[$dst_file_ext];
        $save_dst = 'image' . self::$ext[$dst_file_ext];
        $src = $open_src($src_file);
        $dst = $open_dst($dst_file);
        if(imagesx($src) > imagesx($dst) || imagesy($src) > imagesy($dst) ){
            self::$error = '水印过大!';
            return false;
        }
        if(!imagecopy($dst,$src,$dst_x,$dst_y,0,0,imagesx($src),imagesy($src))){
            self::$error = '水印添加失败!';
            return false;
        }
        $res = $save_dst($dst, $path . 'watermark_' . $dst_file_info['basename']);
        imagedestroy($src);
        imagedestroy($dst);
        if ($res) {     
            return 'watermark_' . $dst_file_info['basename'];
        } else {      
            self::$error = '图片保存失败!';
            return false;
        }
    }
}

//测试
$file1 = '1.jpg';
$path11 = 'thumb/';
$path12 = 'thumb_width/';
$path13 = 'thumb_height/';
$width1 = 400;
$height1 = 240;
//测试固定宽高式缩放
$res = ImageHandler::thumb(array(
    'file' => $file1,
    'path' => $path11,
    'width' => $width1,
    'height' => $height1,
));
if(!$res){
    die(ImageHandler::$error);
}
echo "固定宽高式缩放图片保存成功:thumb/{$res}<br>";
//测试固定宽度式缩放
$res = ImageHandler::thumb(array(
    'file' => $file1,
    'path' => $path12,
    'width' => $width1,
));
if(!$res){
    die(ImageHandler::$error);
}
echo "固定宽度式缩放图片保存成功:thumb_width/{$res}<br>";
//测试固定高度式缩放
$res = ImageHandler::thumb(array(
    'file' => $file1,
    'path' => $path13,
    'height' => $height1,
));
if(!$res){
    die(ImageHandler::$error);
}
echo "固定高度式缩放图片保存成功:thumb_height/{$res}<br>";
//测试图片裁剪
$res = ImageHandler::crop(' 1.jpg  ', ' crop/  ', 400, 400, 600, 200);
if(!$res){
    die(ImageHandler::$error);
}
echo "裁剪图片保存成功:crop/{$res}<br>";
//测试图片水印
$res = ImageHandler::watermark('1.jpg', '  wechat.png', 'watermark/');
if(!$res){
    die(ImageHandler::$error);
}
echo "水印图片保存成功:watermark/{$res}<br>";

 

posted @ 2019-02-23 14:00  chuanzi  阅读(731)  评论(0编辑  收藏  举报