[FastAdmin] 上传图片并加水印,压缩图片
1.app\common\library\Upload.php 文件
upload方法
/**
* 普通上传
* @return \app\common\model\attachment|\think\Model
* @throws UploadException
*/
public function upload($savekey = null)
{
if (empty($this->file)) {
throw new UploadException(__('No file upload or server upload limit exceeded'));
}
$this->checkSize();
$this->checkExecutable();
$this->checkMimetype();
$this->checkImage();
$savekey = $savekey ? $savekey : $this->getSavekey();
$savekey = '/' . ltrim($savekey, '/');
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
$destDir = ROOT_PATH . 'public' . str_replace('/', DS, $uploadDir);
$sha1 = $this->file->hash();
//如果是合并文件
if ($this->merging) {
if (!$this->file->check()) {
throw new UploadException($this->file->getError());
}
$destFile = $destDir . $fileName;
$sourceFile = $this->file->getRealPath() ?: $this->file->getPathname();
$info = $this->file->getInfo();
$this->file = null;
if (!is_dir($destDir)) {
@mkdir($destDir, 0755, true);
}
rename($sourceFile, $destFile);
$file = new File($destFile);
$file->setSaveName($fileName)->setUploadInfo($info);
} else {
$file = $this->file->move($destDir, $fileName);
if (!$file) {
// 上传失败获取错误信息
throw new UploadException($this->file->getError());
}
}
$this->file = $file;
$config=Db::name('config')->where(['group'=>'attachment'])->column('value','name');
if ($config['open_watermark']){
$fontPath = 'assets/fonts/zk.ttf'; // 确保字体文件路径正确,并且该字体支持中文
$this->addTextWatermark('.'.$uploadDir . $file->getSaveName(), '.'.$uploadDir . $file->getSaveName(), $fontPath,$config);
}
//开启图片压缩
if ($config['open_thum']){
if (in_array($this->fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($this->fileInfo['suffix'], ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
$filesize=filesize('.'.$uploadDir . $file->getSaveName());
if ($filesize>200000){
$this->compressImage('.'.$uploadDir . $file->getSaveName(),'.'.$uploadDir . $file->getSaveName(),$config['thum_quality']);
$imgInfo = getimagesize('.'.$uploadDir . $file->getSaveName());
$filesize=filesize('.'.$uploadDir . $file->getSaveName());
$this->fileInfo['size']=$filesize;
$this->fileInfo['imagewidth'] = $imgInfo[0] ?? 0;
$this->fileInfo['imageheight'] = $imgInfo[1] ?? 0;
}
}
}
$category = request()->post('category');
$category = array_key_exists($category, config('site.attachmentcategory') ?? []) ? $category : '';
$auth = Auth::instance();
$params = array(
'admin_id' => (int)session('admin.id'),
'user_id' => (int)$auth->id,
'filename' => mb_substr(htmlspecialchars(strip_tags($this->fileInfo['name'])), 0, 100),
'category' => $category,
'filesize' => $this->fileInfo['size'],
'imagewidth' => $this->fileInfo['imagewidth'],
'imageheight' => $this->fileInfo['imageheight'],
'imagetype' => $this->fileInfo['suffix'],
'imageframes' => 0,
'mimetype' => $this->fileInfo['type'],
'url' => $uploadDir . $file->getSaveName(),
'uploadtime' => time(),
'storage' => 'local',
'sha1' => $sha1,
'extparam' => '',
);
$attachment = new Attachment();
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
return $attachment;
}
/**
* 压缩图片
* @param $sourcePath //需要压缩的图片
* @param $targetPath //压缩后的图片
* @param $quality //压缩质量
* @return bool
*/
public function compressImage($sourcePath, $targetPath, $quality) {
$info = getimagesize($sourcePath);
if ($info !== false) {
$image = imagecreatefromstring(file_get_contents($sourcePath));
imagejpeg($image, $targetPath, $quality); // 质量范围从0(差)到100(好)
imagedestroy($image);
return true;
}
return false;
}
/**
* @param $imagePath 原图
* @param $outputPath 输出图
* @param $text 文字
* @param $fontPath 字体路径
* @param $fontSize 字体大小
* @param $color 字体颜色
* @param $position 位置
* @return void
*/
public function addTextWatermark($imagePath, $outputPath, $fontPath, $config) {
// 创建图片资源
$image = imagecreatefromstring(file_get_contents($imagePath));
// 获取图片尺寸
list($width, $height) = getimagesize($imagePath);
// 设置文字颜色
$black = imagecolorallocatealpha($image, 0, 0, 0, 100); // 最后一个参数是透明度,范围从0(完全透明)到127(完全不透明)
// $textColor = imagecolorallocate($image, hexdec(substr($color, 0, 2)), hexdec(substr($color, 2, 2)), hexdec(substr($color, 4, 2)));
// 设置字体路径和大小
$font = realpath($fontPath);
$fontSize=abs($config['watermark_size']);
if (empty($config['watermark_colour'])) {
$textColor =imagecolortransparent($image, $black);
}else{
$rgb=Checking::hColor2RGB($config['watermark_colour']);
$black = imagecolorallocatealpha($image, $rgb['r'], $rgb['g'], $rgb['b'], 100); // 最后一个参数是透明度,范围从0(完全透明)到127(完全不透明)
$textColor =imagecolortransparent($image, $black);
}
if (empty($config['watermark_text'])){
$text='专用水印';
}else{
$text=$config['watermark_text'];
}
$bbox = imagettfbbox($fontSize, 0, $fontPath, $text); // 获取文字的边界框
$text_width = $bbox[2] - $bbox[0];
$text_height = $bbox[7] - $bbox[1];
if (!empty($config['watermark_position'])) {
if ($width-$text_width*3>50){
$watermark_position=explode(',', $config['watermark_position']);
foreach ($watermark_position as $position) {
switch ($position) {
case 1:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4 , $height/6 , $textColor, $font, $text);
break;
case 2:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4 , $height/6*3 , $textColor, $font, $text);
break;
case 3:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4 , $height/6*5 , $textColor, $font, $text);
break;
case 4:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4*2+$text_width, $height/6 , $textColor, $font, $text);
break;
case 5:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4*2+$text_width, $height/6*3 , $textColor, $font, $text);
break;
case 6:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4*2+$text_width, $height/6*5 , $textColor, $font, $text);
break;
case 7:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4*3+$text_width*2, $height/6 , $textColor, $font, $text);
break;
case 8:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4*3+$text_width*2, $height/6*3 , $textColor, $font, $text);
break;
case 9:
imagettftext($image, $fontSize, 0, ($width - $text_width*3)/4*3+$text_width*2, $height/6*5 , $textColor, $font, $text);
break;
}
}
}
}
// 保存图片
imagejpeg($image, $outputPath);
imagedestroy($image);
}
/**
* 颜色转换 16进制转rgb
* @param $hexColor
* @return array
*/
public static function hColor2RGB($hexColor)
{
$color = str_replace('#', '', $hexColor);
if (strlen($color) > 3) {
$rgb = array(
'r' => hexdec(substr($color, 0, 2)),
'g' => hexdec(substr($color, 2, 2)),
'b' => hexdec(substr($color, 4, 2))
);
} else {
$color = str_replace('#', '', $hexColor);
$r = substr($color, 0, 1) . substr($color, 0, 1);
$g = substr($color, 1, 1) . substr($color, 1, 1);
$b = substr($color, 2, 1) . substr($color, 2, 1);
$rgb = array(
'r' => hexdec($r),
'g' => hexdec($g),
'b' => hexdec($b)
);
}
return $rgb;
}
数据库配置
颜色选择器添加,请参考之前的文章
【FastAdmin】在页面中使用layui,以此引申使用颜色选择器示例-CSDN博客