[TOC] ### 1、先说里面的方法 该类中包含 1.文件上传upload 2.获取图片属性get_image_attr 3.生成缩略图create_image_thumb 4.图片添加水印create_image_water 5.图片裁剪create_image_crop 6.图片翻转create_image_flip 7.图片旋转create_image_rotate 8.图片混合处理image_mixed ### 2、再多一句嘴 里面涉及到创建目录 引入 ~~~ use app\common\controller\Directory //Directory参考***Directory通用封装*** ~~~ 涉及到think\Image 安装topthink-image ### 3、composer 安装 topthink/think-image ~~~ composer require topthink/think-image ~~~ ### 4、文件上传upload ~~~ /** * 文件上传 * * @param string $key files配置文件的key值 * @return array */ public function upload($key = null): array { $file = request()->file('file'); if ($file == null) { return ['status' => false, 'message' => '请上传文件']; } if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } $file_path = './uploads/file/' . explode('.', $key)[1] . '/'; if (!is_dir($file_path)) { (new Directory())->mkdirs($file_path); } //获取配置key $keys = Config::get('files.' . $key); $base_info = $file->getInfo(); $info = $file ->validate(['size' => $keys['size'], 'ext'=> $keys['ext']]) ->rule($keys['rule']) ->move($file_path); $get_success = function () use (&$file_path, &$base_info, &$info) { return [ 'status' => true, 'message' => '上传成功', 'data' => [ 'suffix' => $info->getExtension(), 'size' => $base_info['size'], 'file_path' => $file_path . $info->getSaveName(), 'file_name' => $info->getFilename(), 'base_name' => $base_info['name'], 'base_type' => $base_info['type'], ] ]; }; return $info ? $get_success() : ['status' => false, 'message' => $file->getError()]; } //多句嘴 //该key是在config目录下的files.php配置文件中 //因为代码中使用了文件名files,所以只需传入key即可不带文件名 //方式如下:upload('default.images.default') ~~~ ### 5、插入一段文件上传配置说明 ~~~ // +---------------------------------------------------------------------- // | 文件上传配置 // +---------------------------------------------------------------------- return [ //默认配置 获取配置格式参数$this->upload('default.images.default'); 'default' => [ 'images' => [ //图片上传默认配置 'default' => [ 'size' => 10485760, //rule说明,默认提供date/uniqid/sha1/md5 四种生成文件名的方法 //其中,如果选择date/uniqid 的生成方法的话,相同文件的话不做任何修改 //其他两种则不管是不是同一个文件都会当成新的文件上传 'rule' => 'md5', 'ext' => ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'], ], //值允许上传png后缀的图片 'only_png' => [ 'size' => 10485760, 'rule' => 'md5', 'ext' => ['png'], ], ], 'only_excel' => [ 'size' => 10485760 * 100, 'rule' => 'md5', 'ext' => [ 'xls', 'xlsx' ] ], ], //所有能上传的文件 'all' => [ 'file' => [ 'default' => [ 'size' => 10485760 * 100, 'rule' => 'sha1', 'ext' => [ //图片 'gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf', 'pcx', 'tiff', 'tga', 'exif', 'fpx', 'svg', 'psd', 'cdr', //办公 'xls', 'xlsx', 'xlsm', 'xlt', 'xltx', 'xltm', 'doc', 'docx', 'ppt', 'pps', 'pptx', 'txt', 'pdf', 'md', //视频 'wmv', 'asf', 'asx', 'rm', 'rmvb', 'mpg', 'mpeg', 'mpe', '3gp', 'mov', 'mp4', 'm4v', 'avi', 'dat', 'mkv', 'flv', 'vob', //音频 'mp3', 'ogg', 'ape', 'ape', 'cda', 'au', 'midi', 'mac', 'aac', //压缩 'rar', 'zip', '7z', 'gz', 'bz', 'ace', 'uha', 'uda', 'zpaq', ], ], ], ], ]; ~~~ ### 6、获取图片属性get_image_attr ~~~ //这个直接看代码就好了 /** * 获取图片属性 * * @param string $path 图片地址 * @return array */ public function get_image_attr($path): array { if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } try { $image = Image::open($path); $data = [ 'width' => $image->width(), 'height' => $image->height(), 'type' => $image->type(), 'mime' => $image->mime(), 'size' => $image->size() ]; return ['status' => true, 'message' => '获取属性成功', 'data' => $data]; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 7、图片处理配置文件说明 在后面的方法都是一些图片处理的方法 先贴出配置文件代码 调用的key是config目录下images.php中的key ---相信都能看的懂配置吧-配合代码 ~~~ return [ //缩略图 'thumb' => [ //图片生成缩略图默认配置 'default' => [ 'width' => 150, 'height' => 150, //类型说明: //1、常量,标识缩略图等比例缩放类型 //2、常量,标识缩略图缩放后填充类型 //3、常量,标识缩略图居中裁剪类型 //4、常量,标识缩略图左上角裁剪类型 //5、常量,标识缩略图右下角裁剪类型 //6、常量,标识缩略图固定尺寸缩放类型 'type' => 1, ], ], //添加水印 'water' => [ //图片默认添加水印配置 'default' => [ //水印图片 'img' => './resouce/logo.png', //透明度 'alpha' => 100, //图片显示位置----位置说明 //1、标识左上角水印 //2、标识上居中水印 //3、标识右上角水印 //4、标识左居中水印 //5、标识居中水印 //6、标识右居中水印 //7、标识左下角水印 //8、标识下居中水印 //9、标识右下角水印 'imgtype' => 1, //文字 'text' => '经典宋体', //显示位置tong imagetype 'texttype' => 1, //字体必填且为全路径 'font' => __DIR__ . '../../public/resouce/font/jdsj.ttf', //字体大小 'size' => 20, //字体颜色 'color' => '#00000000', //文字相对当前位置的偏移量 'offset' => 0, //文字倾斜角度 'angle' => 0, ], 'wimg' => [ 'img' => './resouce/logo.png', 'alpha' => 100, 'imgtype' => 1, ], 'wtext' => [ 'text' => '经典宋体', 'texttype' => 1, 'font' => __DIR__ . '../../public/resouce/font/jdsj.ttf', 'size' => 20, 'color' => '#00000000', 'offset' => 0, 'angle' => 0, ], ], //裁剪图片 'crop' => [ //图片默认裁剪配置 'default' => [ //裁剪区域宽度 'cropw' => 150, //裁剪区域高度 'croph' => 150, //裁剪区域x坐标 'x' => 0, //裁剪区域y坐标 'y' => 0, //图像保存宽度 'width' => null, //图像保存高度 'height' => null, ], ], //图像翻转 'flip' => [ //图像翻转默认配置 'default' => [ //图片翻转 type 1=按X轴,2=按Y轴 'type' => 1 ], ], //图片旋转 'rotate' => [ //图片旋转默认配置 'default' => [ //图片旋转 degrees旋转角度 'degrees' => 90 ], ], //混合连续动作--高级配置应用 'mixed' => [ //此默认配置为示例配置--具体操作而应实际情况生产 'default' => [ 'sort0' => ['thumb' => ['width' => 150, 'height' => 150, 'type' => 1]], 'sort1' => ['water' => ['img' => './resouce/logo.png', 'alpha' => 100, 'imgtype' => 1]], 'sort2' => ['crop' => ['cropw' => 150, 'croph' => 150, 'x' => 0, 'y' => 0, 'width' => null, 'height' => null]], 'sort3' => ['flip' => ['type' => 1]], 'sort4' => ['rotate' => ['degrees' => 90]] ], ], ]; ~~~ ### 8、生成缩略图create_image_thumb ~~~ /** * 生成缩略图 * * @param string $path 图片地址 * @param string $key images配置文件中thumb的缩略图配置key * @return array */ public function create_image_thumb($path, $key = null): array { try { if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } if (explode('.', $key)[0] != 'thumb') { return ['status' => false, 'message' => '非法key,不是缩略图的key']; } $keys = Config::get('images.' . $key); if ($keys == null) { return ['status' => false, 'message' => '没有该配置']; } $base_info = explode('.', basename($path)); $image = Image::open($path); $width = $keys['width'] ?? 150; $height = $keys['height'] ?? 150; $type = $keys['type'] ?? 1; $save_path = str_replace(basename($path), '', $path) . $base_info[0] . '_' . $type . '_thumb.' . $base_info[1]; $thumb = $image ->thumb($width, $height, $type) ->save($save_path); $get_success = function () use (&$base_info, &$save_path) { return [ 'status' => true, 'message' => '生成缩略图成功', 'data' => [ 'suffix' => $base_info[1], 'size' => filesize($save_path), 'file_path' => $save_path, 'file_name' => basename($save_path) ] ]; }; return $thumb ? $get_success() : ['status' => false, 'message' => '生成缩略图失败']; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 9、图片添加水印create_image_water ~~~ /** * 图片添加水印 * * @param string $path 图片路径 * @param string $key images配置文件中water的缩略图配置key * @param string $text 当添加文字水印的时候需要手动传入值 * @return array */ public function create_image_water($path, $key = null, $text = null): array { try { if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } if (explode('.', $key)[0] != 'water') { return ['status' => false, 'message' => '非法key,不是加水印的key']; } $keys = Config::get('images.' . $key); if ($keys == null) { return ['status' => false, 'message' => '没有该配置']; } $base_info = explode('.', basename($path)); $image = Image::open($path); $imgtype = $keys['imgtype'] ?? 1; $texttype = $keys['texttype'] ?? 1; $text = $text ?? $keys['text']; $save_path = str_replace(basename($path), '', $path) . $base_info[0] . '_' . $imgtype . $texttype . '_water.' . $base_info[1]; if ($keys['img']) { if (file_exists($keys['img'])) { $alpha = $keys['alpha'] ?? 100; $image->water($keys['img'], $imgtype, $alpha); } else { return ['status' => false, 'message' => '水印图片不存在']; } } if (!empty($text)) { $size = $keys['size'] ?? 20; $color = $keys['color'] ?? '#000000'; $offset = $keys['offset'] ?? 0; $angle = $keys['angle'] ?? 0; $font = $keys['font']; $image->text( mb_convert_encoding($text, 'html-entities', 'UTF-8'), $font, $size, $color, $texttype, $offset, $angle ); } $water = $image->save($save_path); $get_success = function () use (&$base_info, &$save_path) { return [ 'status' => true, 'message' => '添加水印成功', 'data' => [ 'suffix' => $base_info[1], 'size' => filesize($save_path), 'file_path' => $save_path, 'file_name' => basename($save_path) ] ]; }; return $water ? $get_success() : ['status' => false, 'message' => '添加水印失败']; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 10、图片裁剪create_image_crop ~~~ /** * 图片裁剪 * * @param string $path 图片路径 * @param string $key images配置文件中water的缩略图配置key * @return array */ public function create_image_crop($path, $key = null): array { try { if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } if (explode('.', $key)[0] != 'crop') { return ['status' => false, 'message' => '非法key,不是加水印的key']; } $keys = Config::get('images.' . $key); if ($keys == null) { return ['status' => false, 'message' => '没有该配置']; } $base_info = explode('.', basename($path)); $image = Image::open($path); $save_path = str_replace(basename($path), '', $path) . $base_info[0] . '_cut.' . $base_info[1]; $cropw = $keys['cropw'] ?? 150; $croph = $keys['croph'] ?? 150; $x = $keys['x'] ?? 0; $y = $keys['y'] ?? 0; $width = $keys['width'] ?? null; $height = $keys['height'] ?? null; $crop = $image ->crop( $cropw, $croph, $x, $y, $width, $height ) ->save($save_path); $get_success = function () use (&$base_info, &$save_path) { return [ 'status' => true, 'message' => '裁剪图片成功', 'data' => [ 'suffix' => $base_info[1], 'size' => filesize($save_path), 'file_path' => $save_path, 'file_name' => basename($save_path) ] ]; }; return $crop ? $get_success() : ['status' => false, 'message' => '裁剪图片失败']; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 11、图片翻转create_image_flip ~~~ /** * 图片翻转 * * @param string $path 图片路径 * @param string $key images配置文件中flip的缩略图配置key * @return array */ public function create_image_flip($path, $key = null): array { try { if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } if (explode('.', $key)[0] != 'flip') { return ['status' => false, 'message' => '非法key,不是加水印的key']; } $keys = Config::get('images.' . $key); if ($keys == null) { return ['status' => false, 'message' => '没有该配置']; } $base_info = explode('.', basename($path)); $image = Image::open($path); $save_path = str_replace(basename($path), '', $path) . $base_info[0] . '_flip.' . $base_info[1]; $type = $keys['type'] ?? 1; $flip = $image->flip($type)->save($save_path); $get_success = function () use (&$base_info, &$save_path) { return [ 'status' => true, 'message' => '翻转图片成功', 'data' => [ 'suffix' => $base_info[1], 'size' => filesize($save_path), 'file_path' => $save_path, 'file_name' => basename($save_path) ] ]; }; return $flip ? $get_success() : ['status' => false, 'message' => '翻转图片失败']; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 12、图片旋转create_image_rotate ~~~ /** * 图片旋转 * * @param string $path 图片路径 * @param string $key images配置文件中rotate的缩略图配置key * @return array */ public function create_image_rotate($path, $key = null): array { try { if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } if (explode('.', $key)[0] != 'rotate') { return ['status' => false, 'message' => '非法key,不是加水印的key']; } $keys = Config::get('images.' . $key); if ($keys == null) { return ['status' => false, 'message' => '没有该配置']; } $base_info = explode('.', basename($path)); $image = Image::open($path); $save_path = str_replace(basename($path), '', $path) . $base_info[0] . '_rotate.' . $base_info[1]; $degrees = $keys['degrees'] ?? 90; $rotate = $image->rotate($degrees)->save($save_path); $get_success = function () use (&$base_info, &$save_path) { return [ 'status' => true, 'message' => '旋转图片成功', 'data' => [ 'suffix' => $base_info[1], 'size' => filesize($save_path), 'file_path' => $save_path, 'file_name' => basename($save_path) ] ]; }; return $rotate ? $get_success() : ['status' => false, 'message' => '旋转图片失败']; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 13、图片混合处理image_mixed ~~~ /** * 图片混合处理 * * @param integer $type 图片上传处理类型 1表示指定上传图片路径 2表示直接上传 * @param string $key 混合图片上传的key值 * @param string $path 当type=1的时候$path必须指定已知图片路径 * @param string $upkey 当type=2的时候$upkey必须指定上传的key值 * @return array */ public function image_mixed( $type = 1, $key = null, $path = null, $upkey = null ): array { try { //转换int $type = intval($type); //判断是否正确类型 if (!in_array($type, [1, 2])) { return ['status' => false, 'message' => 'type类型不正确']; } //判断key是否存在 if ($key == null) { return ['status' => false, 'message' => 'key不能为空']; } //判断是否是正确的key if (explode('.', $key)[0] != 'mixed') { return ['status' => false, 'message' => '非法key,不是加水印的key']; } //获取key的信息 $keys = Config::get('images.' . $key); //判断key是否有配置 if ($keys == null) { return ['status' => false, 'message' => '没有该配置']; } //判断类型是直接路径还是上传后的路径 if ($type == 2) { $upinfo = $this->upload($upkey); if (!$upinfo['status']) { return $upinfo; } else { $path = $upinfo['data']['file_path']; } } //判断文件路径是否正确,是否存在 if (!file_exists($path)) { return ['status' => false, 'message' => '文件不存在']; } return $this->mixed_image_deal($path, $keys); } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } /** * 处理混合处理 * * @param string $path 图片路径 * @param array $keys 配置值 * @return array */ protected function mixed_image_deal($path, &$keys): array { try { $base_info = explode('.', basename($path)); $image = Image::open($path); $save_path = str_replace(basename($path), '', $path) . $base_info[0] . '_mixed.' . $base_info[1]; //根据键值升序排列 ksort($keys); $image_render = function(&$image_type, &$image) { foreach ($image_type as $key => $val) { switch ($key) { case 'thumb': $width = $val['width'] ?? 150; $height = $val['height'] ?? 150; $type = $val['type'] ?? 1; $image->thumb($width, $height, $type); break; case 'water': $alpha = $val['alpha'] ?? 100; $img = $val['img'] ?? ''; $imgtype = $val['imgtype'] ?? 1; $image->water($img, $imgtype, $alpha); break; case 'text': $text = $val['text']; $texttype = $val['texttype'] ?? 1; $size = $val['size'] ?? 20; $color = $val['color'] ?? '#000000'; $offset = $val['offset'] ?? 0; $angle = $val['angle'] ?? 0; $font = $val['font']; $image->text( mb_convert_encoding($text, 'html-entities', 'UTF-8'), $font, $size, $color, $texttype, $offset, $angle ); break; case 'crop': $cropw = $val['cropw'] ?? 150; $croph = $val['croph'] ?? 150; $x = $val['x'] ?? 0; $y = $val['y'] ?? 0; $width = $val['width'] ?? null; $height = $val['height'] ?? null; $image->crop( $cropw, $croph, $x, $y, $width, $height ); break; case 'flip': $type = $val['type'] ?? 1; $image->flip($type); break; case 'rotate': $degrees = $val['degrees'] ?? 90; $image->rotate($degrees); break; default: throw new \Exception('未找到相应的类型',10006); break; } } }; foreach ($keys as $kd => $kv) { $image_render($kv,$image); } $info = $image->save($save_path); $get_success = function () use (&$base_info, &$save_path) { return [ 'status' => true, 'message' => '操作成功', 'data' => [ 'suffix' => $base_info[1], 'size' => filesize($save_path), 'file_path' => $save_path, 'file_name' => basename($save_path) ] ]; }; return $info ? $get_success() : ['status' => false, 'message' => '操作失败']; } catch (\Exception $e) { return ['status' => false, 'message' => $e->getMessage()]; } } ~~~ ### 14、作者没话说也要说两句 不想解释了 只能相信各位phper的理解能力了 留言说明-解答