用php生成一个新头像,头像内容由2~9张图片组成,比如创建群的时候通过获取9个人组成一张新头像
public function create()
{
// 假设头像路径存储在一个数组中
$avatarPaths = [
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
];
// 创建一个新的图像,假设群头像是120x120像素
$combinedImage = imagecreatetruecolor(120, 120);
// 设置背景颜色,这里设置为白色
$white = imagecolorallocate($combinedImage, 255, 255, 255);
imagefill($combinedImage, 0, 0, $white);
// 头像的尺寸和间距
$avatarSize = 30; // 头像尺寸
// 预设每种人数下的布局
$layouts = [
2 => [[15, 45], [75, 45]],
3 => [[15, 45], [75, 45], [45, 15]],
4 => [[15, 15], [75, 15], [15, 75], [75, 75]],
5 => [[15, 15], [75, 15], [15, 75], [75, 75], [45, 45]],
6 => [[15, 15], [75, 15], [15, 75], [75, 75], [45, 15], [45, 75]],
7 => [[15, 15], [75, 15], [15, 75], [75, 75], [45, 15], [45, 75], [45, 45]],
8 => [[15, 15], [75, 15], [15, 75], [75, 75], [45, 15], [45, 75], [15, 45], [75, 45]],
9 => [[15, 15], [75, 15], [15, 75], [75, 75], [45, 15], [45, 75], [15, 45], [75, 45], [45, 45]],
];
// 限制头像数量在2到9之间
$avatarPaths = array_slice($avatarPaths, 0, 9);
// 循环处理每个头像
foreach ($avatarPaths as $index => $path) {
// 根据文件扩展名确定图像类型并加载头像图像
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
switch ($extension) {
case 'jpg':
case 'jpeg':
$avatarImage = imagecreatefromjpeg($path);
break;
case 'png':
$avatarImage = imagecreatefrompng($path);
break;
default:
// 如果文件类型不支持,跳过该文件
continue 2;
}
// 调整头像大小
$avatarResized = imagescale($avatarImage, $avatarSize, $avatarSize);
// 获取头像位置
$x = $layouts[count($avatarPaths)][$index][0];
$y = $layouts[count($avatarPaths)][$index][1];
// 合并头像到群头像中
imagecopy($combinedImage, $avatarResized, $x, $y, 0, 0, $avatarSize, $avatarSize);
// 销毁不再需要的头像图像
imagedestroy($avatarImage);
imagedestroy($avatarResized);
}
$tmpPath = RUNTIME_PATH . '/tmp/';
if (!file_exists($tmpPath)) {
mkdir($tmpPath, 0777, true);
}
$fileName = $tmpPath . md5(time()) . '.png';
//输出头像
imagejpeg($combinedImage, $fileName);
// 销毁最终的图像
imagedestroy($combinedImage);
// 设置正确的MIME类型
header('Content-Type: image/jpeg');
// 读取并发送图片内容
readfile($fileName);
// 阻止脚本执行,因为已经发送了图片内容
exit;
}
某个用户的头像
拼接效果:
升级版(可以动态适应):
public static function create_avatar($group_sn)
{
$avatarPaths = [
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png',
];
// 创建一个新的图像,假设群头像是120x120像素
$combinedWidth = 500;
$combinedHeight = 500;
$combinedImage = imagecreatetruecolor($combinedWidth, $combinedHeight);
// 设置背景颜色,这里设置为白色
$white = imagecolorallocate($combinedImage, 255, 255, 255);
imagefill($combinedImage, 0, 0, $white);
$tmpPath = RUNTIME_PATH . '/tmp/';
if (!file_exists($tmpPath)) {
@mkdir($tmpPath, 0777, true);
}
$avatarCount = count($avatarPaths);
$default = 'https://foruda.gitee.com/avatar/1698319253150339039/2065616_brisklan_1698319253.png';
$tmpFile = [];
// 根据头像数量动态计算头像大小和布局
if ($avatarCount > 1) {
$rows = ceil(sqrt($avatarCount));
$cols = ceil($avatarCount / $rows);
$avatarSize = min($combinedWidth / $cols, $combinedHeight / $rows);
$paddingX = ($combinedWidth - $avatarSize * $cols) / ($cols + 1);
$paddingY = ($combinedHeight - $avatarSize * $rows) / ($rows + 1);
} else {
$rows = $cols = 1;
$avatarSize = $combinedWidth;
$paddingX = $paddingY = 0;
}
foreach ($avatarPaths as $index => $path) {
if (empty($path) || $path == '/public/images/img88.png') {
$path = $default;
} elseif (stripos($path, 'http') !== 0) {
$path = YZ_URL . $path;
}
//微信的头像先获取下来,jpg方式下面处理才好,请听劝
if (stripos($path, 'thirdwx.qlogo.cn') !== false) {
file_put_contents($tmpPath . '/' . md5($path) . '.jpg', file_get_contents($path));
$path = str_replace('\\', '/', $tmpPath . '/' . md5($path) . '.jpg');
$tmpFile[] = $path;
}
$extension = strtolower(pathinfo($path, PATHINFO_EXTENSION));
switch ($extension) {
case 'jpg':
case 'jpeg':
$avatarImage = imagecreatefromjpeg($path);
break;
case 'png':
$avatarImage = imagecreatefrompng($path);
break;
default:
continue 2;
}
$avatarResized = imagescale($avatarImage, $avatarSize, $avatarSize);
$row = floor($index / $cols);
$col = $index % $cols;
$x = $paddingX + $col * ($avatarSize + $paddingX);
$y = $paddingY + $row * ($avatarSize + $paddingY);
imagecopy($combinedImage, $avatarResized, $x, $y, 0, 0, $avatarSize, $avatarSize);
imagedestroy($avatarImage);
imagedestroy($avatarResized);
}
$fileName = $tmpPath . $group_sn . '.png';
imagejpeg($combinedImage, $fileName);
imagedestroy($combinedImage);
if (!file_exists(dirname($fileName))) {
return $default;
}
//输出图片
header('Content-Type: image/jpeg');
readfile($fileName);
exit();
}
效果: