用php根据头像数组生成群头像

用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;

    }


某个用户的头像image.png


拼接效果:

image.png


升级版(可以动态适应):

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();

   
}

效果:image.png

评论/留言