用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(); }
效果: