Browse Source

聊天上传图片压缩,新增返回原图接口5

master
wanghongjun 7 months ago
parent
commit
70f8a29834
  1. 189
      app/common/controller/Upload.php

189
app/common/controller/Upload.php

@ -422,80 +422,47 @@ class Upload extends BaseController
// 处理图地址
$target = root_path().'public/' .ltrim($compress_path,'/');
// 图片模糊处理
if (class_exists('Imagick')) {
$compress_res = $this->slightBlurImagick($filePath, $target, 1);
} else {
$compress_res = $this->slightBlurGD($filePath, $target, 1);
}
$compress_res = $this->slightBlurGD($filePath, $target);
if (!$compress_res) {
return '';
}
return $compress_path;
}
// 使用Imagick添加轻微模糊
protected function slightBlurImagick($source, $target, $blurLevel)
{
try {
$imagick = new \Imagick($source);
// 轻微模糊 (半径0.5-2.0)
$radius = min(2.0, max(0.5, $blurLevel * 0.5));
$imagick->gaussianBlurImage($radius, 1);
// 保存时降低质量
$extension = strtolower(pathinfo($target, PATHINFO_EXTENSION));
switch ($extension) {
case 'jpg':
case 'jpeg':
$imagick->setImageCompressionQuality(85);
$imagick->setImageFormat('jpeg');
break;
case 'webp':
case 'png':
$imagick->setImageCompressionQuality(85);
break;
}
return $imagick->writeImage($target);
} catch (\Exception $e) {
\think\facade\Log::error('Imagick模糊处理失败: ' . $e->getMessage());
return false;
}
}
// 使用GD库添加轻微模糊
protected function slightBlurGD($source, $target, $blurLevel)
protected function slightBlurGD($imageFile, $target)
{
$info = getimagesize($source);
$type = $info[2];
// 创建图像资源
switch ($type) {
// 获取图片信息
list($imgWidth, $imgHeight, $imageType) = getimagesize($imageFile);
// 根据图片类型创建图像资源
switch ($imageType) {
case IMAGETYPE_JPEG:
$image = imagecreatefromjpeg($source);
$image = imagecreatefromjpeg($imageFile);
break;
case IMAGETYPE_PNG:
$image = imagecreatefrompng($source);
$image = imagecreatefrompng($imageFile);
// 保留透明通道
imagealphablending($image, true);
imagesavealpha($image, true);
break;
case IMAGETYPE_GIF:
$image = imagecreatefromgif($source);
break;
case IMAGETYPE_WEBP:
$image = imagecreatefromwebp($source);
$image = imagecreatefromgif($imageFile);
break;
default:
return false;
}
// 应用轻微模糊
for ($i = 0; $i < $blurLevel; $i++) {
imagefilter($image, IMG_FILTER_GAUSSIAN_BLUR);
}
// 获取图片尺寸
// 调整选择区域确保在图片范围内
$x = 0;
$y = 0;
// 应用马赛克效果
$this->applyMosaic($image, $x, $y, $imgWidth, $imgHeight, 5, 2);
// 保存图片
switch ($type) {
switch ($imageType) {
case IMAGETYPE_JPEG:
imagejpeg($image, $target, 85);
break;
@ -510,7 +477,119 @@ class Upload extends BaseController
break;
}
imagedestroy($image);
return true;
}
/**
* 应用马赛克效果
*
* @param resource $image 图像资源
* @param int $x 起始X坐标
* @param int $y 起始Y坐标
* @param int $width 区域宽度
* @param int $height 区域高度
* @param int $blockSize 马赛克块大小
* @param int $blurStrength 模糊强度 (1-3)
*/
protected function applyMosaic($image, $x, $y, $width, $height, $blockSize, $blurStrength) {
// 调整马赛克块大小
$adjustedBlockSize = $blockSize * $blurStrength;
// 计算马赛克网格
$cols = ceil($width / $adjustedBlockSize);
$rows = ceil($height / $adjustedBlockSize);
// 处理每个马赛克块
for ($row = 0; $row < $rows; $row++) {
for ($col = 0; $col < $cols; $col++) {
// 计算当前块的区域
$blockX = $x + $col * $adjustedBlockSize;
$blockY = $y + $row * $adjustedBlockSize;
$blockWidth = min($adjustedBlockSize, $width - $col * $adjustedBlockSize);
$blockHeight = min($adjustedBlockSize, $height - $row * $adjustedBlockSize);
// 计算块内像素的平均颜色
$avgColor = $this->calculateAverageColor($image, $blockX, $blockY, $blockWidth, $blockHeight);
// 填充整个块为平均颜色
imagefilledrectangle(
$image,
$blockX,
$blockY,
$blockX + $blockWidth - 1,
$blockY + $blockHeight - 1,
$avgColor
);
}
}
// 根据需要应用额外模糊
if ($blurStrength > 1) {
$blurRegion = imagecrop($image, ['x' => $x, 'y' => $y, 'width' => $width, 'height' => $height]);
if ($blurRegion !== false) {
// 应用模糊
for ($i = 0; $i < $blurStrength; $i++) {
imagefilter($blurRegion, IMG_FILTER_GAUSSIAN_BLUR);
}
// 将模糊后的区域放回原图
imagecopymerge($image, $blurRegion, $x, $y, 0, 0, $width, $height, 100);
imagedestroy($blurRegion);
}
}
}
/**
* 计算图像区域的平均颜色
*
* @param resource $image 图像资源
* @param int $x 起始X坐标
* @param int $y 起始Y坐标
* @param int $width 区域宽度
* @param int $height 区域高度
* @return int 颜色标识符
*/
protected function calculateAverageColor($image, $x, $y, $width, $height) {
$totalR = 0;
$totalG = 0;
$totalB = 0;
$totalAlpha = 0;
$pixelCount = 0;
// 遍历区域内的所有像素
for ($i = 0; $i < $width; $i++) {
for ($j = 0; $j < $height; $j++) {
$px = $x + $i;
$py = $y + $j;
// 确保像素在图像范围内
if ($px >= imagesx($image)) continue;
if ($py >= imagesy($image)) continue;
// 获取像素颜色
$color = imagecolorat($image, $px, $py);
$rgba = imagecolorsforindex($image, $color);
// 累加颜色值
$totalR += $rgba['red'];
$totalG += $rgba['green'];
$totalB += $rgba['blue'];
$totalAlpha += $rgba['alpha'];
$pixelCount++;
}
}
// 计算平均值
if ($pixelCount === 0) {
return imagecolorallocatealpha($image, 0, 0, 0, 127);
}
$avgR = round($totalR / $pixelCount);
$avgG = round($totalG / $pixelCount);
$avgB = round($totalB / $pixelCount);
$avgAlpha = round($totalAlpha / $pixelCount);
// 返回平均颜色
return imagecolorallocatealpha($image, $avgR, $avgG, $avgB, $avgAlpha);
}
}

Loading…
Cancel
Save