生成二维码和邀请海报
方案一
php
if(!function_exists('createInviteImg')){
// 生成推广员邀请码图片
function createInviteImg($promoter_code, $promoter_name, $promoter_code_id){
// 邀请海报背景图
$inviteBgImg = '/assets/img/inviteBgImg.png';
$site = Config::get("site");
if(array_key_exists('inviteBgImg',$site)){
$inviteBgImg = $site['inviteBgImg'];
}
// 生成二维码
$text = cdnurl("/promoter_invite?promoter_code=".$promoter_code,true); // 微信扫码跳转到小程序
list($filePath,$fileUrl) = buildQrcode($text, '', '/uploads/qrcode/promoter/', 'code_'.$promoter_code_id.'_'.time(), true, 20);
// 生成邀请海报
$fileUrl = '/uploads/qrcode/promoter/promoter_'. $promoter_code_id.'_'.time().'.jpg';
$filename = ROOT_PATH .'public'. $fileUrl;
$config = array(
'image'=>array(
array(
'url'=>$filePath, //二维码地址
'stream'=>0,
'left'=>-1, //小于0为小平居中
'top'=>927,
'right'=>0,
'width'=>284, //图像宽
'height'=>284, //图像高
'opacity'=>100, //透明度
),
),
'text'=>array(
array(
'text'=>'邀请码:'.$promoter_code, //文字内容
'left'=>-1, //小于0为水平居中
'top'=>910,
'fontSize'=>20, //字号
'fontColor'=>'255,255,255', //字体颜色
'angle'=>0,
'fontPath'=>ROOT_PATH.'public/assets/fonts/msyh/msyh.ttf', //字体文件
)
),
'background'=>ROOT_PATH.'public'.$inviteBgImg, //背景图
// 'background'=>cdnurl('/assets/img/haibao.png',true), //背景图
);
//echo createPoster($config);
//$filename为空是真接浏览器显示图片
createPoster($config,$filename);
// 删除二维码文件
@unlink($filePath);
return $fileUrl;
// return cdnurl($fileUrl,true);
}
}
if (!function_exists('buildQrcode')) {
// 生成二维码
function buildQrcode($text, $label, $file_url, $name='', $rounded=true, $radius = 20)
{
$params = [
'text' => $text,
'size' => 284, //大小
'padding' => 7, //内边距
'errorlevel' => 'medium', //容错级别:low-低 medium-中等 quartile-高 high-超高
'foreground' => "#000000", //前景色
'background' => "#ffffff", //背景色
'logo' => 0, //Logo:1-显示,0-不显示
'logosize' => '', //Logo大小
'label' => $label, //标签
'labelfontsize' => 16, //标签大小
'labelalignment' => 'center', //标签水平位置:left-左 center-中 right-右
];
$qrCode = \addons\qrcode\library\Service::qrcode($params);
$response = Response::create()->header("Content-Type", "image/png");
// 直接显示二维码
header('Content-Type: ' . $qrCode->getMimeType());
$response->content($qrCode->getString());
// 写入到文件
$file_name = $name?$name:md5(implode('', $params));
$fileUrl = $file_url . $file_name . '.png';
$filePath = ROOT_PATH .'public'. $fileUrl;
if (!file_exists(ROOT_PATH .'public/uploads/qrcode/')) mkdir (ROOT_PATH .'public/uploads/qrcode/',0777,true);
if (!file_exists(ROOT_PATH .'public'.$file_url)) mkdir (ROOT_PATH .'public'.$file_url,0777,true);
$qrCode->saveToFile($filePath);
// 如果启用圆角,处理二维码图片
if ($rounded) {
$roundedFilePath = ROOT_PATH . 'public' . $file_url . $file_name . '_rounded.png';
$roundedFileUrl = $file_url . $file_name . '_rounded.png';
// 生成圆角二维码
$result = applyRoundedCornersToImage($filePath, $roundedFilePath, $radius);
if ($result) {
@unlink($filePath);
// 使用圆角二维码文件路径
$filePath = $roundedFilePath;
$fileUrl = $roundedFileUrl;
}
}
return [$filePath,$fileUrl];
}
}
/**
* 给图片添加圆角
* @param string $sourcePath 源图片路径
* @param string $destPath 目标图片路径
* @param int $radius 圆角半径
* @return bool 是否成功
*/
function applyRoundedCornersToImage($sourcePath, $destPath, $radius = 20) {
// 获取图片信息
$info = getimagesize($sourcePath);
if ($info === false) {
return false;
}
// 根据图片类型创建图像资源
$imageType = $info[2];
switch ($imageType) {
case IMAGETYPE_PNG:
$sourceImage = imagecreatefrompng($sourcePath);
break;
case IMAGETYPE_JPEG:
$sourceImage = imagecreatefromjpeg($sourcePath);
break;
case IMAGETYPE_GIF:
$sourceImage = imagecreatefromgif($sourcePath);
break;
default:
return false;
}
if (!$sourceImage) {
return false;
}
$width = imagesx($sourceImage);
$height = imagesy($sourceImage);
// 创建新图像
$roundedImage = imagecreatetruecolor($width, $height);
// 设置透明背景
imagealphablending($roundedImage, false);
imagesavealpha($roundedImage, true);
$transparent = imagecolorallocatealpha($roundedImage, 0, 0, 0, 127);
imagefill($roundedImage, 0, 0, $transparent);
// 创建圆角遮罩
$mask = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($mask, 255, 255, 255);
$black = imagecolorallocate($mask, 0, 0, 0);
imagefill($mask, 0, 0, $white);
// 绘制黑色圆角矩形(这是我们要保留的区域)
drawRoundedRect($mask, 0, 0, $width, $height, $radius, $black);
// 应用遮罩
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$maskColor = imagecolorat($mask, $x, $y);
$maskRgb = imagecolorsforindex($mask, $maskColor);
// 如果遮罩是黑色(在圆角矩形内),复制原图像素
if ($maskRgb['red'] == 0 && $maskRgb['green'] == 0 && $maskRgb['blue'] == 0) {
$srcColor = imagecolorat($sourceImage, $x, $y);
$srcRgb = imagecolorsforindex($sourceImage, $srcColor);
$newColor = imagecolorallocatealpha(
$roundedImage,
$srcRgb['red'],
$srcRgb['green'],
$srcRgb['blue'],
$srcRgb['alpha']
);
imagesetpixel($roundedImage, $x, $y, $newColor);
}
}
}
// 保存圆角图片
imagepng($roundedImage, $destPath, 9);
// 释放资源
imagedestroy($sourceImage);
imagedestroy($roundedImage);
imagedestroy($mask);
return true;
}
/**
* 绘制圆角矩形
*/
function drawRoundedRect($image, $x, $y, $width, $height, $radius, $color) {
// 确保半径不超过矩形的一半
$radius = min($radius, floor($width / 2), floor($height / 2));
// 绘制四个圆角
imagefilledarc($image, $x + $radius, $y + $radius, $radius * 2, $radius * 2, 180, 270, $color, IMG_ARC_PIE);
imagefilledarc($image, $x + $width - $radius, $y + $radius, $radius * 2, $radius * 2, 270, 360, $color, IMG_ARC_PIE);
imagefilledarc($image, $x + $width - $radius, $y + $height - $radius, $radius * 2, $radius * 2, 0, 90, $color, IMG_ARC_PIE);
imagefilledarc($image, $x + $radius, $y + $height - $radius, $radius * 2, $radius * 2, 90, 180, $color, IMG_ARC_PIE);
// 绘制矩形部分
imagefilledrectangle($image, $x + $radius, $y, $x + $width - $radius, $y + $radius, $color);
imagefilledrectangle($image, $x, $y + $radius, $x + $radius, $y + $height - $radius, $color);
imagefilledrectangle($image, $x + $radius, $y + $height - $radius, $x + $width - $radius, $y + $height, $color);
imagefilledrectangle($image, $x + $width - $radius, $y + $radius, $x + $width, $y + $height - $radius, $color);
// 填充中间区域
imagefilledrectangle($image, $x + $radius, $y + $radius, $x + $width - $radius, $y + $height - $radius, $color);
}
if (!function_exists('createPoster')) {
/**
* 生成宣传海报(优化版,正确处理透明PNG)
*/
function createPoster($config = array(), $filename = "") {
if (empty($filename)) {
header("content-type: image/png");
}
// 默认图片参数
$imageDefault = array(
'left' => 0,
'top' => 0,
'right' => 0,
'bottom' => 0,
'width' => 100,
'height' => 100,
'opacity' => 100
);
// 默认文字参数
$textDefault = array(
'text' => '',
'left' => 0,
'top' => 0,
'fontSize' => 32,
'fontColor' => '255,255,255',
'angle' => 0,
);
// 加载背景图片
$backgroundPath = $config['background'];
if (!file_exists($backgroundPath)) {
die('背景图片不存在: ' . $backgroundPath);
}
$background = imagecreatefromstring(file_get_contents($backgroundPath));
if (!$background) {
die('无法加载背景图片');
}
$backgroundWidth = imagesx($background);
$backgroundHeight = imagesy($background);
// 创建海报画布
$poster = imagecreatetruecolor($backgroundWidth, $backgroundHeight);
// 复制背景到海报
imagecopy($poster, $background, 0, 0, 0, 0, $backgroundWidth, $backgroundHeight);
// 处理图片元素
if (!empty($config['image'])) {
foreach ($config['image'] as $val) {
$val = array_merge($imageDefault, $val);
// 加载图片
if (!file_exists($val['url'])) {
continue;
}
$imageContent = file_get_contents($val['url']);
if (!$imageContent) {
continue;
}
$srcImage = imagecreatefromstring($imageContent);
if (!$srcImage) {
continue;
}
$srcWidth = imagesx($srcImage);
$srcHeight = imagesy($srcImage);
// 创建临时画布
$tempCanvas = imagecreatetruecolor($val['width'], $val['height']);
// 设置透明背景
imagesavealpha($tempCanvas, true);
imagealphablending($tempCanvas, false);
$transparent = imagecolorallocatealpha($tempCanvas, 0, 0, 0, 127);
imagefill($tempCanvas, 0, 0, $transparent);
// 重新采样图片
imagecopyresampled($tempCanvas, $srcImage, 0, 0, 0, 0, $val['width'], $val['height'], $srcWidth, $srcHeight);
// 计算位置
if ($val['left'] < 0) {
$val['left'] = ceil(($backgroundWidth - $val['width']) / 2);
}
if ($val['top'] < 0) {
$val['top'] = ceil(($backgroundHeight - $val['height']) / 2);
}
// 合并到海报
imagecopy($poster, $tempCanvas, $val['left'], $val['top'], 0, 0, $val['width'], $val['height']);
imagedestroy($srcImage);
imagedestroy($tempCanvas);
}
}
// 处理文字
if (!empty($config['text'])) {
foreach ($config['text'] as $val) {
$val = array_merge($textDefault, $val);
// 设置字体颜色
list($R, $G, $B) = explode(',', $val['fontColor']);
$fontColor = imagecolorallocate($poster, $R, $G, $B);
// 计算文字位置
if ($val['left'] < 0) {
// 水平居中
$fontPath = isset($val['fontPath']) ? $val['fontPath'] : '';
if ($fontPath && file_exists($fontPath)) {
$bbox = imagettfbbox($val['fontSize'], $val['angle'], $fontPath, $val['text']);
if ($bbox) {
$textWidth = $bbox[2] - $bbox[0];
$val['left'] = ceil(($backgroundWidth - $textWidth) / 2);
}
}
}
// 添加文字
if (isset($val['fontPath']) && file_exists($val['fontPath'])) {
imagettftext($poster, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
}
}
}
// 输出或保存图片
if (!empty($filename)) {
// 确保目录存在
$dir = dirname($filename);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
// 保存为JPEG
imagejpeg($poster, $filename, 90);
imagedestroy($poster);
imagedestroy($background);
return file_exists($filename) ? $filename : false;
} else {
// 直接输出
header('Content-Type: image/jpeg');
imagejpeg($poster);
imagedestroy($poster);
imagedestroy($background);
exit;
}
}
}
// 不能生成显示出二维码的圆角(不能正确处理透明PNG)
// if (!function_exists('createPoster')) {
// /**
// * 生成宣传海报
// * @param array 参数,包括图片和文字
// * @param string $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
// * @return [type] [description]
// */
// function createPoster($config = array() , $filename = "") {
// if (empty($filename)) header("content-type: image/png");
// $imageDefault = array(
// 'left' => 0,
// 'top' => 0,
// 'right' => 0,
// 'bottom' => 0,
// 'width' => 100,
// 'height' => 100,
// 'opacity' => 100,
// 'radius' => 0, // 新增:圆角半径,0表示直角
// 'is_yuan' => false // 兼容旧参数,圆形裁剪
// );
// $textDefault = array(
// 'text' => '',
// 'left' => 0,
// 'top' => 0,
// 'fontSize' => 32, //字号
// 'fontColor' => '255,255,255', //字体颜色
// 'angle' => 0,
// );
// $background = $config['background']; //海报最底层得背景
// //背景方法
// $backgroundInfo = getimagesize($background);
// $backgroundFun = 'imagecreatefrom' . image_type_to_extension($backgroundInfo[2], false);
// $background = $backgroundFun($background);
// $backgroundWidth = imagesx($background); //背景宽度
// $backgroundHeight = imagesy($background); //背景高度
// $imageRes = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
// $color = imagecolorallocate($imageRes, 255, 255, 255); //背景图默认填充颜色为白色
// 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']);
// $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
// if ($val['stream']) { //如果传的是字符串图像流
// $info = getimagesizefromstring($val['url']);
// $function = 'imagecreatefromstring';
// }
// $res = $function($val['url']);
// $resWidth = $info[0];
// $resHeight = $info[1];
// //建立画板 ,缩放图片至指定尺寸
// $canvas = imagecreatetruecolor($val['width'], $val['height']);
// imagefill($canvas, 0, 0, $color);
// //如果是透明的gif或png做透明处理
// $ext = pathinfo($val['url']);
// if (array_key_exists('extension',$ext)) {
// if ($ext['extension'] == 'gif' || $ext['extension'] == 'png') {
// // imageColorTransparent($canvas, $color); //颜色透明
// }
// }
// //关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
// imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
// //$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
// //如果left小于-1我这做成了计算让其水平居中
// if ($val['left'] < 0) {
// $val['left'] = ceil($backgroundWidth - $val['width']) / 2;
// }
// $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']); //左,上,右,下,宽度,高度,透明度
// }
// }
// //处理文字
// if (!empty($config['text'])) {
// foreach ($config['text'] as $key => $val) {
// $val = array_merge($textDefault, $val);
// list($R, $G, $B) = explode(',', $val['fontColor']);
// $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
// //$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
// //如果left小于-1我这做成了计算让其水平居中
// if ($val['left'] < 0) {
// $fontBox = imagettfbbox($val['fontSize'], 0, $val['fontPath'], $val['text']); //文字水平居中实质
// $val['left'] = ceil(($backgroundWidth - $fontBox[2]) / 2); //计算文字的水平位置
// }
// $val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) : $val['top'];
// imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
// }
// }
// //生成图片
// if (!empty($filename)) {
// $res = imagejpeg($imageRes, $filename, 90); //保存到本地
// imagedestroy($imageRes);
// if (!$res) return false;
// return $filename;
// } else {
// header("Content-type:image/png");
// imagejpeg($imageRes); //在浏览器上显示
// imagedestroy($imageRes);
// }
// }
// }
方案二(参数动态配置)
php
if(!function_exists('createInviteImg')){
// 生成推广员邀请码图片
function createInviteImg($promoter_code, $promoter_name, $promoter_code_id){
$site = Config::get("site");
// 邀请海报背景图
$inviteBgImg = isset($site['inviteBgImg'])&& $site['inviteBgImg'] ? $site['inviteBgImg'] : '/assets/img/inviteBgImg.png';
// 二维码宽度px
$codeWidth = isset($site['codeWidth'])&& $site['codeWidth'] ? $site['codeWidth'] : 284;
// 二维码内边距px
$codePadding = isset($site['codePadding'])&& $site['codePadding'] ? $site['codePadding'] : 7;
// 二维码圆角px
$codeRadius = isset($site['codeRadius'])&& $site['codeRadius'] ? $site['codeRadius'] : 20;
// 二维码与海报顶部距离px
$codeTop = isset($site['codeTop'])&& $site['codeTop'] ? $site['codeTop'] : 927;
// 邀请码前缀
$invatePrefix = isset($site['invatePrefix'])&& $site['invatePrefix'] ? $site['invatePrefix'] : '邀请码:';
// 邀请码字号大小px
$invateFontSize = isset($site['invateFontSize'])&& $site['invateFontSize'] ? $site['invateFontSize'] : 20;
// 邀请码字体颜色
$invateFontColor = isset($site['invateFontColor'])&& $site['invateFontColor'] ? $site['invateFontColor'] : '255,255,255';
// 邀请码与海报顶部距离px
$invateTop = isset($site['invateTop'])&& $site['invateTop'] ? $site['invateTop'] : 910;
// 生成二维码
$text = cdnurl("/promoter_invite?promoter_code=".$promoter_code,true); // 微信扫码跳转到小程序
list($filePath,$fileUrl) = buildQrcode($text, '', '/uploads/qrcode/promoter/', 'code_'.$promoter_code_id.'_'.time(), $codeWidth, $codePadding, true, $codeRadius);
// 生成邀请海报
$fileUrl = '/uploads/qrcode/promoter/promoter_'. $promoter_code_id.'_'.time().'.jpg';
$filename = ROOT_PATH .'public'. $fileUrl;
$config = array(
'image'=>array(
array(
'url'=>$filePath, //二维码地址
'stream'=>0,
'left'=>-1, //小于0为小平居中
'top'=>$codeTop,
'right'=>0,
'width'=>$codeWidth, //图像宽
'height'=>$codeWidth, //图像高
'opacity'=>100, //透明度
),
),
'text'=>array(
array(
'text'=>$invatePrefix.$promoter_code, //文字内容
'left'=>-1, //小于0为水平居中
'top'=>$invateTop,
'fontSize'=>$invateFontSize, //字号
'fontColor'=>$invateFontColor, //字体颜色
'angle'=>0,
'fontPath'=>ROOT_PATH.'public/assets/fonts/msyh/msyh.ttf', //字体文件
)
),
'background'=>ROOT_PATH.'public'.$inviteBgImg, //背景图
// 'background'=>cdnurl('/assets/img/haibao.png',true), //背景图
);
//echo createPoster($config);
//$filename为空是真接浏览器显示图片
createPoster($config,$filename);
// 删除二维码文件
@unlink($filePath);
return $fileUrl;
// return cdnurl($fileUrl,true);
}
}
if (!function_exists('buildQrcode')) {
// 生成二维码
function buildQrcode($text, $label, $file_url, $name='', $width, $padding, $rounded=true, $radius = 20)
{
$params = [
'text' => $text,
'size' => $width, //大小
'padding' => $padding, //内边距
'errorlevel' => 'medium', //容错级别:low-低 medium-中等 quartile-高 high-超高
'foreground' => "#000000", //前景色
'background' => "#ffffff", //背景色
'logo' => 0, //Logo:1-显示,0-不显示
'logosize' => '', //Logo大小
'label' => $label, //标签
'labelfontsize' => 16, //标签大小
'labelalignment' => 'center', //标签水平位置:left-左 center-中 right-右
];
$qrCode = \addons\qrcode\library\Service::qrcode($params);
$response = Response::create()->header("Content-Type", "image/png");
// 直接显示二维码
header('Content-Type: ' . $qrCode->getMimeType());
$response->content($qrCode->getString());
// 写入到文件
$file_name = $name?$name:md5(implode('', $params));
$fileUrl = $file_url . $file_name . '.png';
$filePath = ROOT_PATH .'public'. $fileUrl;
if (!file_exists(ROOT_PATH .'public/uploads/qrcode/')) mkdir (ROOT_PATH .'public/uploads/qrcode/',0777,true);
if (!file_exists(ROOT_PATH .'public'.$file_url)) mkdir (ROOT_PATH .'public'.$file_url,0777,true);
$qrCode->saveToFile($filePath);
// 如果启用圆角,处理二维码图片
if ($rounded) {
$roundedFilePath = ROOT_PATH . 'public' . $file_url . $file_name . '_rounded.png';
$roundedFileUrl = $file_url . $file_name . '_rounded.png';
// 生成圆角二维码
$result = applyRoundedCornersToImage($filePath, $roundedFilePath, $radius);
if ($result) {
@unlink($filePath);
// 使用圆角二维码文件路径
$filePath = $roundedFilePath;
$fileUrl = $roundedFileUrl;
}
}
return [$filePath,$fileUrl];
}
}
/**
* 给图片添加圆角
* @param string $sourcePath 源图片路径
* @param string $destPath 目标图片路径
* @param int $radius 圆角半径
* @return bool 是否成功
*/
function applyRoundedCornersToImage($sourcePath, $destPath, $radius = 20) {
// 获取图片信息
$info = getimagesize($sourcePath);
if ($info === false) {
return false;
}
// 根据图片类型创建图像资源
$imageType = $info[2];
switch ($imageType) {
case IMAGETYPE_PNG:
$sourceImage = imagecreatefrompng($sourcePath);
break;
case IMAGETYPE_JPEG:
$sourceImage = imagecreatefromjpeg($sourcePath);
break;
case IMAGETYPE_GIF:
$sourceImage = imagecreatefromgif($sourcePath);
break;
default:
return false;
}
if (!$sourceImage) {
return false;
}
$width = imagesx($sourceImage);
$height = imagesy($sourceImage);
// 创建新图像
$roundedImage = imagecreatetruecolor($width, $height);
// 设置透明背景
imagealphablending($roundedImage, false);
imagesavealpha($roundedImage, true);
$transparent = imagecolorallocatealpha($roundedImage, 0, 0, 0, 127);
imagefill($roundedImage, 0, 0, $transparent);
// 创建圆角遮罩
$mask = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($mask, 255, 255, 255);
$black = imagecolorallocate($mask, 0, 0, 0);
imagefill($mask, 0, 0, $white);
// 绘制黑色圆角矩形(这是我们要保留的区域)
drawRoundedRect($mask, 0, 0, $width, $height, $radius, $black);
// 应用遮罩
for ($x = 0; $x < $width; $x++) {
for ($y = 0; $y < $height; $y++) {
$maskColor = imagecolorat($mask, $x, $y);
$maskRgb = imagecolorsforindex($mask, $maskColor);
// 如果遮罩是黑色(在圆角矩形内),复制原图像素
if ($maskRgb['red'] == 0 && $maskRgb['green'] == 0 && $maskRgb['blue'] == 0) {
$srcColor = imagecolorat($sourceImage, $x, $y);
$srcRgb = imagecolorsforindex($sourceImage, $srcColor);
$newColor = imagecolorallocatealpha(
$roundedImage,
$srcRgb['red'],
$srcRgb['green'],
$srcRgb['blue'],
$srcRgb['alpha']
);
imagesetpixel($roundedImage, $x, $y, $newColor);
}
}
}
// 保存圆角图片
imagepng($roundedImage, $destPath, 9);
// 释放资源
imagedestroy($sourceImage);
imagedestroy($roundedImage);
imagedestroy($mask);
return true;
}
/**
* 绘制圆角矩形
*/
function drawRoundedRect($image, $x, $y, $width, $height, $radius, $color) {
// 确保半径不超过矩形的一半
$radius = min($radius, floor($width / 2), floor($height / 2));
// 绘制四个圆角
imagefilledarc($image, $x + $radius, $y + $radius, $radius * 2, $radius * 2, 180, 270, $color, IMG_ARC_PIE);
imagefilledarc($image, $x + $width - $radius, $y + $radius, $radius * 2, $radius * 2, 270, 360, $color, IMG_ARC_PIE);
imagefilledarc($image, $x + $width - $radius, $y + $height - $radius, $radius * 2, $radius * 2, 0, 90, $color, IMG_ARC_PIE);
imagefilledarc($image, $x + $radius, $y + $height - $radius, $radius * 2, $radius * 2, 90, 180, $color, IMG_ARC_PIE);
// 绘制矩形部分
imagefilledrectangle($image, $x + $radius, $y, $x + $width - $radius, $y + $radius, $color);
imagefilledrectangle($image, $x, $y + $radius, $x + $radius, $y + $height - $radius, $color);
imagefilledrectangle($image, $x + $radius, $y + $height - $radius, $x + $width - $radius, $y + $height, $color);
imagefilledrectangle($image, $x + $width - $radius, $y + $radius, $x + $width, $y + $height - $radius, $color);
// 填充中间区域
imagefilledrectangle($image, $x + $radius, $y + $radius, $x + $width - $radius, $y + $height - $radius, $color);
}
if (!function_exists('createPoster')) {
/**
* 生成宣传海报(优化版,正确处理透明PNG)
*/
function createPoster($config = array(), $filename = "") {
if (empty($filename)) {
header("content-type: image/png");
}
// 默认图片参数
$imageDefault = array(
'left' => 0,
'top' => 0,
'right' => 0,
'bottom' => 0,
'width' => 100,
'height' => 100,
'opacity' => 100
);
// 默认文字参数
$textDefault = array(
'text' => '',
'left' => 0,
'top' => 0,
'fontSize' => 32,
'fontColor' => '255,255,255',
'angle' => 0,
);
// 加载背景图片
$backgroundPath = $config['background'];
if (!file_exists($backgroundPath)) {
die('背景图片不存在: ' . $backgroundPath);
}
$background = imagecreatefromstring(file_get_contents($backgroundPath));
if (!$background) {
die('无法加载背景图片');
}
$backgroundWidth = imagesx($background);
$backgroundHeight = imagesy($background);
// 创建海报画布
$poster = imagecreatetruecolor($backgroundWidth, $backgroundHeight);
// 复制背景到海报
imagecopy($poster, $background, 0, 0, 0, 0, $backgroundWidth, $backgroundHeight);
// 处理图片元素
if (!empty($config['image'])) {
foreach ($config['image'] as $val) {
$val = array_merge($imageDefault, $val);
// 加载图片
if (!file_exists($val['url'])) {
continue;
}
$imageContent = file_get_contents($val['url']);
if (!$imageContent) {
continue;
}
$srcImage = imagecreatefromstring($imageContent);
if (!$srcImage) {
continue;
}
$srcWidth = imagesx($srcImage);
$srcHeight = imagesy($srcImage);
// 创建临时画布
$tempCanvas = imagecreatetruecolor($val['width'], $val['height']);
// 设置透明背景
imagesavealpha($tempCanvas, true);
imagealphablending($tempCanvas, false);
$transparent = imagecolorallocatealpha($tempCanvas, 0, 0, 0, 127);
imagefill($tempCanvas, 0, 0, $transparent);
// 重新采样图片
imagecopyresampled($tempCanvas, $srcImage, 0, 0, 0, 0, $val['width'], $val['height'], $srcWidth, $srcHeight);
// 计算位置
if ($val['left'] < 0) {
$val['left'] = ceil(($backgroundWidth - $val['width']) / 2);
}
if ($val['top'] < 0) {
$val['top'] = ceil(($backgroundHeight - $val['height']) / 2);
}
// 合并到海报
imagecopy($poster, $tempCanvas, $val['left'], $val['top'], 0, 0, $val['width'], $val['height']);
imagedestroy($srcImage);
imagedestroy($tempCanvas);
}
}
// 处理文字
if (!empty($config['text'])) {
foreach ($config['text'] as $val) {
$val = array_merge($textDefault, $val);
// 设置字体颜色
list($R, $G, $B) = explode(',', $val['fontColor']);
$fontColor = imagecolorallocate($poster, $R, $G, $B);
// 计算文字位置
if ($val['left'] < 0) {
// 水平居中
$fontPath = isset($val['fontPath']) ? $val['fontPath'] : '';
if ($fontPath && file_exists($fontPath)) {
$bbox = imagettfbbox($val['fontSize'], $val['angle'], $fontPath, $val['text']);
if ($bbox) {
$textWidth = $bbox[2] - $bbox[0];
$val['left'] = ceil(($backgroundWidth - $textWidth) / 2);
}
}
}
// 添加文字
if (isset($val['fontPath']) && file_exists($val['fontPath'])) {
imagettftext($poster, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
}
}
}
// 输出或保存图片
if (!empty($filename)) {
// 确保目录存在
$dir = dirname($filename);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
// 保存为JPEG
imagejpeg($poster, $filename, 90);
imagedestroy($poster);
imagedestroy($background);
return file_exists($filename) ? $filename : false;
} else {
// 直接输出
header('Content-Type: image/jpeg');
imagejpeg($poster);
imagedestroy($poster);
imagedestroy($background);
exit;
}
}
}
效果图示:

