|
|
@@ -287,7 +287,7 @@ class UtilService
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * TODO 生成分享二维码图片(增强版:支持圆形头像、透明、错误处理)
|
|
|
+ * TODO 生成分享二维码图片
|
|
|
* @param array $config
|
|
|
* @param $path
|
|
|
* @return array|bool|string
|
|
|
@@ -302,117 +302,48 @@ class UtilService
|
|
|
'bottom' => 0,
|
|
|
'width' => 100,
|
|
|
'height' => 100,
|
|
|
- 'opacity' => 100,
|
|
|
- 'circle' => false, // 新增:圆形蒙版
|
|
|
- 'border_width' => 0, // 新增:边框宽(px)
|
|
|
- 'border_color' => '0,0,0' // 新增:边框色 RGB
|
|
|
+ 'opacity' => 100
|
|
|
);
|
|
|
$textDefault = array(
|
|
|
'text' => '',
|
|
|
'left' => 0,
|
|
|
'top' => 0,
|
|
|
- 'fontSize' => 32,
|
|
|
- 'fontColor' => '255,255,255',
|
|
|
+ 'fontSize' => 32, //字号
|
|
|
+ 'fontColor' => '255,255,255', //字体颜色
|
|
|
'angle' => 0,
|
|
|
);
|
|
|
- $background = $config['background'];
|
|
|
+ $background = $config['background'];//海报最底层得背景
|
|
|
if (substr($background, 0, 1) === '/') {
|
|
|
$background = substr($background, 1);
|
|
|
}
|
|
|
- $bgInfo = getimagesize($background);
|
|
|
- if (!$bgInfo) return '背景图无效';
|
|
|
+ $backgroundInfo = getimagesize($background);
|
|
|
$background = imagecreatefromstring(file_get_contents($background));
|
|
|
- if (!$background) return '背景图加载失败';
|
|
|
- $backgroundWidth = $bgInfo[0];
|
|
|
- $backgroundHeight = $bgInfo[1];
|
|
|
- $imageRes = imagecreatetruecolor($backgroundWidth, $backgroundHeight);
|
|
|
- $black = imagecolorallocate($imageRes, 0, 0, 0);
|
|
|
- imagefill($imageRes, 0, 0, $black);
|
|
|
- imagecopyresampled($imageRes, $background, 0, 0, 0, 0, $backgroundWidth, $backgroundHeight, imagesx($background), imagesy($background));
|
|
|
- imagedestroy($background);
|
|
|
-
|
|
|
- $hasCircle = false; // 新增:检测是否 PNG 输出
|
|
|
+ $backgroundWidth = $backgroundInfo[0]; //背景宽度
|
|
|
+ $backgroundHeight = $backgroundInfo[1]; //背景高度
|
|
|
+ $imageRes = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
|
|
|
+ $color = imagecolorallocate($imageRes, 0, 0, 0);
|
|
|
+ imagefill($imageRes, 0, 0, $color);
|
|
|
+ imagecopyresampled($imageRes, $background, 0, 0, 0, 0, imagesx($background), imagesy($background), imagesx($background), imagesy($background));
|
|
|
if (!empty($config['image'])) {
|
|
|
foreach ($config['image'] as $key => $val) {
|
|
|
$val = array_merge($imageDefault, $val);
|
|
|
- $info = @getimagesize($val['url']); // 加@
|
|
|
- if (!$info) {
|
|
|
- error_log("海报图像加载失败: {$val['url']}"); // 日志
|
|
|
- continue; // 跳过无效图
|
|
|
- }
|
|
|
- $ext = image_type_to_extension($info[2], false);
|
|
|
- $function = 'imagecreatefrom' . $ext;
|
|
|
+ $info = getimagesize($val['url']);
|
|
|
+ $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
|
|
|
if ($val['stream']) {
|
|
|
- $info = @getimagesizefromstring($val['url']);
|
|
|
+ $info = getimagesizefromstring($val['url']);
|
|
|
$function = 'imagecreatefromstring';
|
|
|
}
|
|
|
- $res = @$function($val['url']);
|
|
|
- if (!$res) {
|
|
|
- error_log("海报图像创建失败: {$val['url']}, type: $ext");
|
|
|
- continue;
|
|
|
- }
|
|
|
+ $res = $function($val['url']);
|
|
|
$resWidth = $info[0];
|
|
|
$resHeight = $info[1];
|
|
|
-
|
|
|
- // ===== 修复:透明 canvas =====
|
|
|
$canvas = imagecreatetruecolor($val['width'], $val['height']);
|
|
|
- imagesavealpha($canvas, true);
|
|
|
- imagealphablending($canvas, false);
|
|
|
- $transparent = imagecolorallocatealpha($canvas, 0, 0, 0, 127);
|
|
|
- imagefill($canvas, 0, 0, $transparent);
|
|
|
-
|
|
|
- // 合成源图
|
|
|
- imagealphablending($canvas, true);
|
|
|
+ imagefill($canvas, 0, 0, $color);
|
|
|
imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
|
|
|
- imagedestroy($res);
|
|
|
-
|
|
|
- // ===== 新增:圆形蒙版 =====
|
|
|
- if ($val['circle']) {
|
|
|
- $hasCircle = true;
|
|
|
- $radius = min($val['width'], $val['height']) / 2 - 1;
|
|
|
- $centerX = $val['width'] / 2;
|
|
|
- $centerY = $val['height'] / 2;
|
|
|
-
|
|
|
- // 创建蒙版(白圆 = 保留,透明外)
|
|
|
- $mask = imagecreatetruecolor($val['width'], $val['height']);
|
|
|
- imagesavealpha($mask, true);
|
|
|
- imagefill($mask, 0, 0, $transparent);
|
|
|
- $maskWhite = imagecolorallocatealpha($mask, 255, 255, 255, 0); // 全不透明白
|
|
|
- imagefilledellipse($mask, $centerX, $centerY, $radius * 2, $radius * 2, $maskWhite);
|
|
|
-
|
|
|
- // 像素蒙版合成(高效小图)
|
|
|
- for ($x = 0; $x < $val['width']; $x++) {
|
|
|
- for ($y = 0; $y < $val['height']; $y++) {
|
|
|
- $maskRgb = imagecolorat($mask, $x, $y);
|
|
|
- $alpha = 127 - (($maskRgb >> 16) & 0x7F); // 白→低alpha(保留)
|
|
|
- if ($alpha > 64) { // 阈值,外透明
|
|
|
- imagesetpixel($canvas, $x, $y, $transparent);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- imagedestroy($mask);
|
|
|
- }
|
|
|
-
|
|
|
- // ===== 新增:边框(可选,圆形增强) =====
|
|
|
- if ($val['border_width'] > 0) {
|
|
|
- list($r, $g, $b) = explode(',', $val['border_color']);
|
|
|
- $borderColor = imagecolorallocate($canvas, $r, $g, $b);
|
|
|
- $borderRadius = min($val['width'], $val['height']) / 2;
|
|
|
- imagefilledellipse($canvas, $centerX, $centerY, $borderRadius * 2, $borderRadius * 2, $borderColor);
|
|
|
- // 内减边框宽
|
|
|
- $innerRadius = $borderRadius - $val['border_width'] * 2;
|
|
|
- imagefilledellipse($canvas, $centerX, $centerY, $innerRadius * 2, $innerRadius * 2, $transparent);
|
|
|
- }
|
|
|
-
|
|
|
- // 位置调整 + 合成
|
|
|
$val['left'] = $val['left'] < 0 ? $backgroundWidth - abs($val['left']) - $val['width'] : $val['left'];
|
|
|
$val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) - $val['height'] : $val['top'];
|
|
|
- imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']);
|
|
|
- imagedestroy($canvas);
|
|
|
+ imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']);//左,上,右,下,宽度,高度,透明度
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // 文字不变(你的动态 left 已完美)
|
|
|
if (isset($config['text']) && !empty($config['text'])) {
|
|
|
foreach ($config['text'] as $key => $val) {
|
|
|
$val = array_merge($textDefault, $val);
|
|
|
@@ -423,24 +354,20 @@ class UtilService
|
|
|
imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- // ===== 输出:PNG if circle =====
|
|
|
ob_start();
|
|
|
- $key = substr(md5(rand(0, 9999)), 0, 5) . date('YmdHis') . rand(0, 999999);
|
|
|
- $key .= $hasCircle ? '.png' : '.jpg';
|
|
|
- if ($hasCircle) {
|
|
|
- imagesavealpha($imageRes, true);
|
|
|
- imagepng($imageRes);
|
|
|
- } else {
|
|
|
- imagejpeg($imageRes);
|
|
|
- }
|
|
|
+ imagejpeg($imageRes);
|
|
|
imagedestroy($imageRes);
|
|
|
$res = ob_get_contents();
|
|
|
ob_end_clean();
|
|
|
-
|
|
|
- // 上传不变
|
|
|
+ $key = substr(md5(rand(0, 9999)), 0, 5) . date('YmdHis') . rand(0, 999999) . '.jpg';
|
|
|
$uploadType = (int)sys_config('upload_type', 1);
|
|
|
- $upload = new Upload($uploadType, [ /* 配置不变 */ ]);
|
|
|
+ $upload = new Upload($uploadType, [
|
|
|
+ 'accessKey' => sys_config('accessKey'),
|
|
|
+ 'secretKey' => sys_config('secretKey'),
|
|
|
+ 'uploadUrl' => sys_config('uploadUrl'),
|
|
|
+ 'storageName' => sys_config('storage_name'),
|
|
|
+ 'storageRegion' => sys_config('storage_region'),
|
|
|
+ ]);
|
|
|
$res = $upload->to($path)->validate()->stream($res, $key);
|
|
|
if ($res === false) {
|
|
|
return $upload->getError();
|
|
|
@@ -452,7 +379,6 @@ class UtilService
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
/**
|
|
|
* TODO 获取小程序二维码是否生成
|
|
|
* @param $url
|