zoukankan      html  css  js  c++  java
  • 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>";
  • 相关阅读:
    mysql 语句case when
    Hibernate应用SQL查询返回实体类型
    JavaBean 和 Map 之间互相转换
    基于注解风格的Spring-MVC的拦截器
    Spring MVC与表单日期提交的问题
    自适应网页设计(Responsive Web Design)
    JSP页面用EL表达式 输出date格式
    EL表达式中如何截取字符串
    DOCTYPE html PUBLIC 指定了 HTML 文档遵循的文档类型定义
    javascript对table的添加,删除行的操作
  • 原文地址:https://www.cnblogs.com/chuanzi/p/10422497.html
Copyright © 2011-2022 走看看