现阶段我负责的业务有上传图片功能。现阶段前端使用的是VUE3,我在使用前端对图片进行压缩,具体请移步《VUE3(三十六)压缩base64格式图片》如题,我这里只对base64格式的图片进行压缩,正常的图片文件压缩上文中并没有涉及到。
后来我突发奇想,前端都能压缩图片,那我后端能不能压缩图片呢?那应该是可能得吧。经过一段学习+百度,就有了下边我写的这个压缩图片类,代码如下:
<?php
namespace App\Http\Model;
/**
* @name: 压缩图片类
* @author: camellia
* @date: 2021-10-08
*/
class ImgCompress
{
/**
* @name: 文件绝对路径
* @author: camellia
* @date: 2021-10-08
*/
private $src;
/**
* @name: 图片对象
* @author: camellia
* @date: 2021-10-08
*/
private $image;
/**
* @name: 图片信息
* @author: camellia
* @date: 2021-10-08
*/
private $imageinfo;
/**
* @name: 图片压缩比
* @author: camellia
* @date: 2021-10-08
*/
private $percent = 0.5;
/*
* 图片压缩
* @param $src 源图
* @param float $percent 压缩比例
*/
public function __construct($src, $percent = 0.5)
{
$this->src = $src;
$this->percent = $percent;
}
/** 高清压缩图片
* @param string $saveName 提供图片名(可不带扩展名,用源图扩展名)用于保存。或不提供文件名直接显示
* @desc 'uploads/studentRecord/1111.png' 存储在 网站根目录下的 ./uploads/studentRecord 目录中
* @desc '1111.png' 直接存储在 网站根目录下
*/
public function compressImg($saveName = '')
{
$this->_openImage();
if (!empty($saveName))
{
$this->_saveImage($saveName); //保存
}
else
{
$this->_showImage();
}
}
/**
* @name: 内部:打开图片
* @author: camellia
* @date: 2021-10-08
*/
private function _openImage()
{
// =======================================================================
// 根据图片大小调整压缩比例,根据自己需要添加
$size = filesize($this->src);
// 大于5M
if($size > 5242880)
{
$this->percent = 0.3;
}
else if($size > 1048576)
{ // 大于1M
$this->percent = 0.4;
}
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();
}
/**
* @name: 内部:操作图片
* @author: camellia
* @date: 2021-10-08
*/
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;
}
/**
* @name: 输出图片:保存图片则用saveImage()
* @author: camellia
* @date: 2021-10-08
*/
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;
}
$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'];
// var_dump($funcs); # imagejpeg() 函数
// var_dump($dstName); # 文件名称
// var_dump($this->image);die;
$funcs($this->image, $dstName);
}
/**
* @name: 销毁图片
* @author: camellia
* @date: 2021-10-08
*/
public function __destruct()
{
imagedestroy($this->image);
}
}
调用代码:
//压缩图片 即 压缩比例 默认不传为 0.5,数据在 0-1 之间
(new ImgCompress("要压缩的图片", 0.8))->compressImg("图片压缩之后存储位置");
测试了一下,压缩效果还是可以的,但是有一个小小的问题:在用户使用高峰期上传图片的时候,会出现卡顿。查看服务器使用状态,发现只有带宽占用的特别高。所以吧,尽量能在客户端处理的问题尽量在客户端处理。
以上大概就是PHP压缩图片的基本使用。
有好的建议,请在下方输入你的评论。