From 1c367eb68702ea1980d940acf6163944328678ce Mon Sep 17 00:00:00 2001 From: kuaifan Date: Mon, 3 Apr 2023 11:01:38 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Models/WebSocketDialogMsg.php | 3 + app/Module/ImgCompress.php | 152 ++++++++++++++++++++++++++++++ 2 files changed, 155 insertions(+) create mode 100644 app/Module/ImgCompress.php diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index 7750f9917..fa4d3a744 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Module\ImgCompress; use Carbon\Carbon; use App\Models\User; use App\Module\Base; @@ -587,6 +588,7 @@ class WebSocketDialogMsg extends AbstractModel Base::makeDir(public_path($imagePath)); $imagePath .= md5s($base64) . "." . $matchs[1][$key]; if (file_put_contents(public_path($imagePath), base64_decode($base64))) { + ImgCompress::compress(public_path($imagePath)); $imageSize = getimagesize(public_path($imagePath)); if (Base::imgThumb(public_path($imagePath), public_path($imagePath) . "_thumb.jpg", 320, 0)) { $imagePath .= "_thumb.jpg"; @@ -661,6 +663,7 @@ class WebSocketDialogMsg extends AbstractModel if (empty($image)) { $text = str_replace($matchs[0][$key], "[:IMAGE:browse:90:90:images/other/imgerr.jpg::]", $text); } else if (file_put_contents(public_path($imagePath), $image)) { + ImgCompress::compress(public_path($imagePath)); $imageSize = getimagesize(public_path($imagePath)); if (Base::imgThumb(public_path($imagePath), public_path($imagePath) . "_thumb.jpg", 320, 0)) { $imagePath .= "_thumb.jpg"; diff --git a/app/Module/ImgCompress.php b/app/Module/ImgCompress.php new file mode 100644 index 000000000..d13fc406a --- /dev/null +++ b/app/Module/ImgCompress.php @@ -0,0 +1,152 @@ +src = $src; + $this->percent = $percent; + } + + /** 高清压缩图片 + * @param string $saveName 提供图片名(可不带扩展名,用源图扩展名)用于保存。或不提供文件名直接显示 + */ + public function compressImg($saveName = '') + { + $this->_openImage(); + if (!empty($saveName)) $this->_saveImage($saveName); //保存 + else $this->_showImage(); + } + + /** + * 内部:打开图片 + */ + private function _openImage() + { + list($width, $height, $type, $attr) = getimagesize($this->src); + $this->imageinfo = array( + 'width' => $width, + 'height' => $height, + 'type' => image_type_to_extension($type, false), + 'attr' => $attr + ); + $fun = "imagecreatefrom" . $this->imageinfo['type']; + $this->image = $fun($this->src); + $this->_thumpImage(); + } + + /** + * 内部:操作图片 + */ + private function _thumpImage() + { + $new_width = $this->imageinfo['width'] * $this->percent; + $new_height = $this->imageinfo['height'] * $this->percent; + $image_thump = imagecreatetruecolor($new_width, $new_height); + //将原图复制带图片载体上面,并且按照一定比例压缩,极大的保持了清晰度 + imagecopyresampled($image_thump, $this->image, 0, 0, 0, 0, $new_width, $new_height, $this->imageinfo['width'], $this->imageinfo['height']); + imagedestroy($this->image); + $this->image = $image_thump; + } + + /** + * 输出图片:保存图片则用saveImage() + */ + private function _showImage() + { + header('Content-Type: image/' . $this->imageinfo['type']); + $funcs = "image" . $this->imageinfo['type']; + $funcs($this->image); + } + + /** + * 保存图片到硬盘: + * @param string $dstImgName 1、可指定字符串不带后缀的名称,使用源图扩展名 。2、直接指定目标图片名带扩展名。 + */ + private function _saveImage($dstImgName) + { + if (empty($dstImgName)) return false; + if (str_contains($dstImgName, '.')) { + $dstName = $dstImgName; + } else { + $allowImgs = ['.jpg', '.jpeg', '.png', '.bmp', '.wbmp', '.gif']; //如果目标图片名有后缀就用目标图片扩展名 后缀,如果没有,则用源图的扩展名 + $dstExt = strrchr($dstImgName, "."); + $sourseExt = strrchr($this->src, "."); + if (!empty($dstExt)) $dstExt = strtolower($dstExt); + if (!empty($sourseExt)) $sourseExt = strtolower($sourseExt); + //有指定目标名扩展名 + if (!empty($dstExt) && in_array($dstExt, $allowImgs)) { + $dstName = $dstImgName; + } elseif (!empty($sourseExt) && in_array($sourseExt, $allowImgs)) { + $dstName = $dstImgName . $sourseExt; + } else { + $dstName = $dstImgName . $this->imageinfo['type']; + } + } + $funcs = "image" . $this->imageinfo['type']; + $funcs($this->image, $dstName); + return true; + } + + /** + * 销毁图片 + */ + public function __destruct() + { + imagedestroy($this->image); + } + + /** + * 压缩图片静态方法 + * @param string $src 原图地址 + * @param float $percent 压缩比例 + * @param float $minSize 最小压缩大小,小于这个不压缩,单位KB + * @return void + */ + public static function compress(string $src, float $percent = 1, float $minSize = 100): void + { + if (!file_exists($src)) { + return; + } + $size = filesize($src); + if ($minSize > 0 && $size < $minSize * 1024) { + return; + } + try { + $img = new ImgCompress($src, $percent); + $tmp = $src . '.compress.tmp'; + $img->compressImg($tmp); + if (file_exists($tmp)) { + if (filesize($tmp) > $size) { + unlink($tmp); + return; + } + unlink($src); + rename($tmp, $src); + } + } catch (\Exception) { + return; + } + } +}