压缩图片
本文参考源自博主: 前端萌新&初级后端攻城狮 的文章,灰常感谢,亲测可用
图片压缩其实很多场景都会用得上, 著名的有 tinypng 压缩服务.
博主之前也经常用 tinypng 但是感觉有点限制.
所以试着用 GD 库简单实现一下压缩图片, 当然这样的压缩是有损的.
/**
* @param $params
* ['photo'] // 图片地址
* ['quality'] // 图片压缩后的质量 值范围: 1 - 75 默认值 50
* ['like_width'] // 偏好宽度, 如果图片宽度大于该宽度值 会自动压缩为该宽度的数字大小 默认为 900PX
* ['cover'] // 是否覆盖原图 0为不覆盖 1为覆盖
* @return false|string
*/
function compressPicture($params)
{
$gd_info = gd_info();
if (empty($gd_info['GD Version'])) exit('请安装GD库');
if (empty($params['photo'])) exit('请输入图片地址');
if (!file_exists($params['photo'])) exit('图片文件不存在');
$quality = $params['quality'] ?? 50;
if ($quality < 1 || $quality > 75) exit('压缩质量错误');
$like_width = $params['like_width'] ?? 900;
// 获取图片信息(高度和宽度)
$photo_file = file_get_contents($params['photo']);
$photo_size = getimagesizefromstring($photo_file);
$photo_width = $photo_size[0];
$photo_height = $photo_size[1];
$new_width = $photo_width;
$new_height = $photo_height;
// 使用原图创建新画布
switch ($photo_size['mime']){
case 'image/jpeg':
$image = imagecreatefromjpeg($params['photo']);
break;
case 'image/gif':
$image = imagecreatefromgif($params['photo']);
break;
case 'image/png':
$image = imagecreatefrompng($params['photo']);
break;
}
if (!isset($image)) exit('请上传图片或图片格式错误');
if ($photo_width > $like_width) {
// 裁剪图片尺寸
$new_width = $like_width;
$proportion = $like_width / $photo_width;
$new_height = $proportion * $photo_height;
}
$new_image = imagecreatetruecolor($new_width, $new_height);
if ($photo_size['mime'] == 'image/png') {
// 解决 PNG 格式图片透明背景
$color = imagecolorallocate($new_image,255,255,255); // 为一幅图像分配颜色
imagecolortransparent($new_image, $color); // 设置透明
imagealphablending($new_image, false); // 设定图像的混色模式
imagesavealpha($new_image, true); // 设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息
}
imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $photo_width, $photo_height);
$ext = pathinfo($params['photo'],PATHINFO_EXTENSION);
$new_photo_name = md5(time() . mt_rand(1000, 9999)) . '.' . $ext;
if (!empty($params['cover'])) {
// 覆盖原图
$new_photo_name = $params['photo'];
}
switch ($photo_size['mime']){
case 'image/jpeg':
imagejpeg($new_image, $new_photo_name, $quality);
break;
case 'image/gif':
imagegif($new_image, $new_photo_name);
break;
case 'image/png':
imagepng($new_image, $new_photo_name);
break;
}
// 销毁资源
imagedestroy($image);
imagedestroy($new_image);
return json_encode([
'code' => 0,
'url' => $new_photo_name,
]);
}
可以在方法外面增加一个判断:
if ($_GET['action'] == 'compress_picture') {
// 图片压缩
exit(compressPicture($_GET));
}
增加水印:
/**
* @param $params
*
* 水印所需参数:
* ['photo'] // 图片地址
* ['content'] // 水印内容(如果是文字水印 则直接传文字内容 如果是图片水印 传图片路径)
* ['x'] // 水印所在位置的 X 轴坐标
* ['y'] // 水印所在位置的 Y 轴坐标
* ['type'] // 1图片水印 2文字水印
* ['cover'] // 是否覆盖原图 0为不覆盖 1为覆盖
*
* @return false|string
*/
function addWatermark($params)
{
$gd_info = gd_info();
if (empty($gd_info['GD Version'])) exit('请安装GD库');
if (empty($params['photo'])) exit('请输入图片地址');
if (!file_exists($params['photo'])) exit('图片文件不存在');
if(empty($params['content'])) exit('缺少水印内容');
$x = 10;
$y = 30;
if (!empty($params['x']) && is_numeric($params['x'])) $x = $params['x'];
if (!empty($params['y']) && is_numeric($params['y'])) $y = $params['y'];
// 获取图片信息(高度和宽度)
$photo_file = file_get_contents($params['photo']);
$photo_size = getimagesizefromstring($photo_file);
$photo_width = $photo_size[0];
$photo_height = $photo_size[1];
// 使用原图创建新画布
switch ($photo_size['mime']){
case 'image/jpeg':
$image = imagecreatefromjpeg($params['photo']);
break;
case 'image/gif':
$image = imagecreatefromgif($params['photo']);
break;
case 'image/png':
$image = imagecreatefrompng($params['photo']);
break;
}
if (!isset($image)) exit('请上传图片或图片格式错误');
$new_image = imagecreatetruecolor($photo_width, $photo_height);
if ($photo_size['mime'] == 'image/png') {
// 解决 PNG 格式图片透明背景
$color = imagecolorallocate($new_image,255,255,255); // 为一幅图像分配颜色
imagecolortransparent($new_image, $color); // 设置透明
imagealphablending($new_image, false); // 设定图像的混色模式
imagesavealpha($new_image, true); // 设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息
}
imagecopyresampled(
$new_image,
$image,
0,
0,
0,
0,
$photo_width,
$photo_height,
$photo_width,
$photo_height
);
// 增加图片水印
if ($params['type'] == 1) {
$watermark_info = getimagesize($params['content']);
// 获取水印图片的类型
$watermark_type = image_type_to_extension($watermark_info[2], false);
// 在内存创建图像
$watermark_create_image_function = "imagecreatefrom{$watermark_type}";
// 把水印图片复制到内存中
$watermark = $watermark_create_image_function($params['content']);
// 特别处理设置透明
// $color = imagecolorallocate($watermark, 255, 255, 255);
// imagefill($watermark, 0, 0, $color);
// imagecolortransparent($watermark, $color);
// 合并图片
imagecopymerge($new_image, $watermark, $x, $y, 0, 0, $watermark_info[0], $watermark_info[1], 100);
}
// 增加文字水印
if ($params['type'] == 2) {
// 字体颜色默认值
$red = $params['red'] ?? 255;
$green = $params['green'] ?? 255;
$blue = $params['blue'] ?? 255;
$alpha = $params['alpha'] ?? 0;
if (!is_numeric($red) || !is_numeric($green) || !is_numeric($blue) || !is_numeric($alpha)) exit('字体颜色错误');
$color = imagecolorallocatealpha($new_image, $red, $green, $blue, $alpha); // 设置字体颜色和透明度
// 字体大小
$font_size = $params['font_size'] ?? 30;
$font_path = __DIR__ . '/wen.ttf';
// 写入文字
imagettftext($new_image, $font_size, 0, $x, $y, $color, $font_path, $params['content']);
}
$ext = pathinfo($params['photo'],PATHINFO_EXTENSION);
$new_photo_name = md5(time() . mt_rand(1000, 9999)) . '.' . $ext;
if (!empty($params['cover'])) {
// 覆盖原图
$new_photo_name = $params['photo'];
}
switch ($photo_size['mime']){
case 'image/jpeg':
imagejpeg($new_image, $new_photo_name);
break;
case 'image/gif':
imagegif($new_image, $new_photo_name);
break;
case 'image/png':
imagepng($new_image, $new_photo_name);
break;
}
// 销毁资源
imagedestroy($image);
imagedestroy($new_image);
return json_encode([
'code' => 0,
'url' => $new_photo_name,
]);
}
在方法外面继续增加一个判断:
if ($_GET['action'] == 'add_watermark') {
// 图片加水印
exit(addWatermark($_GET));
}
网友评论