uni-app+php 生成微信二维码 分销海报

时间:2024-06-01 07:16:04

主要代码如下,可直接复制调试参数:

 //查询当前用户是否有分销海报
    public function user_poster(){
        $this->checkAuth();
        //查询会员信息
        $user = $this->getUserInfoById($this->user_id);
        if(!empty($user['distribution_img'])){
            $result['data'] = $user['distribution_img'];
        }else{
            $result = $this->getDistributorImg();
        }
        $this->success("请求成功!", $result);

    }
    

    //获取小程序分享二维码--分销海报
    public function getDistributorImg()
    {
        try{
            //查询会员信息
            $userinfo = $this->getUserInfoById($this->user_id);
            $url = $this->request->get('url');
            $save_dir = 'upload/qr_code/user_share/';
            $save_key = 'uid'.$userinfo['id'];
            $img_src = md5($save_key) . '.png';

            $poster_config = $this->userShareConfig();

            $poster_url = root_path().'public/'.$save_dir . $img_src;
            //生成小程序二维码
            $res = $this->makeUserMnpQrcode($userinfo,$save_key,$img_src);
            if(true !== $res){
                return ['status' => 0, 'msg' => '微信配置错误:'.$res, 'data' => ''];
            }
            $background_img = root_path().'public/images/share_user_bg.png';

            $user_avatar =  root_path().'public/images/default_logo.jpg';
            $qr_code_logic = new MemberController();
            //获取背景图
            $share_background_img = imagecreatefromstring(file_get_contents($background_img));
            //合成头像
            $qr_code_logic->writeImg($share_background_img, $user_avatar, $poster_config['head_pic'],true);

            //合成昵称
            $nickname = self::filterEmoji($userinfo['nickname']);
            $qr_code_logic->writeText($share_background_img, $nickname, $poster_config['nickname']);
            //长按识别
            $notice = '长按识别二维码 >>';
            $qr_code_logic->writeText($share_background_img, $notice, $poster_config['notice']);
            //合成商品标题
            $title = self::auto_adapt($poster_config['title']['font_size'], 0, $poster_config['title']['font_face'], '邀请你一起来赚大钱', $poster_config['title']['w'],$poster_config['title']['y'],getimagesize($background_img));
            $qr_code_logic->writeText($share_background_img, $title, $poster_config['title']);
            //邀请码
            $qr_code_logic->writeText($share_background_img, '邀请码 '.$userinfo['distribution_code'], $poster_config['code_text']);
            //合成二维码
            $qr_code_logic->writeImg($share_background_img, $poster_url, $poster_config['qr'],false);

            imagepng($share_background_img, $poster_url);

            $file_name = 'public/'.$save_dir . $img_src;
            $result['data'] = $file_name;
            $dis_oss_img = $this->local_upload($result['data']);

            //更新会员分销海报信息
            $dis_oss_img = cmf_get_asset_url($dis_oss_img);
            $this->up_member(['distribution_img' => $dis_oss_img]);
            //上传oss
            $result['data'] = $dis_oss_img;
            return $result;

        }catch(Exception $e){
            return ['status' => 0, 'msg' => $e->getMessage(), 'data' => ''];
        }
        
    }

    public function up_member($params)
    {
        $this->checkAuth();

        $this->MemberModel = new MemberModel();
        $params['update_time'] = time();
        $member                = $this->getUserInfoByOpenid($this->openid);

        if (empty($member)) $this->error("该会员不存在!");


        $result = $this->MemberModel->where('id', $member['id'])->strict(false)->update($params);
        if ($result) {
            $result = $this->getUserInfoById($this->user_id);
            return true;
        } else {
            return false;
        }
    }

需要引用的方法

/*
 * 生成海报自动适应标题
 */
public function auto_adapt($size, $angle = 0, $fontfile, $string, $width, $height, $bg_height)
{
    $content = "";
    // 将字符串拆分成一个个单字 保存到数组 letter 中
    for ($i = 0; $i < mb_strlen($string); $i++) {
        $letters[] = mb_substr($string, $i, 1);
    }

    foreach ($letters as $letter) {
        $str = $content . " " . $letter;
        $box = imagettfbbox($size, $angle, $fontfile, $str);

        $total_height = $box[1] + $height;
        if ($bg_height[1] - $total_height < $size) {
            break;
        }
        //右下角X位置,判断拼接后的字符串是否超过预设的宽度
        if (($box[2] > $width) && ($content !== "")) {
            if ($bg_height[1] - $total_height < $size * 2) {
                break;
            }
            $content .= "\n";
        }
        $content .= $letter;
    }
    return $content;
}

    //写入文字
    public function writeText($poster, $text, $config){

        $font_uri = $config['font_face'];
        $font_size = $config['font_size'];
        $color = substr($config['color'],1);
        //颜色转换
        $color= str_split($color, 2);
        $color = array_map('hexdec', $color);
        if (empty($color[3]) || $color[3] > 127) {
            $color[3] = 0;
        }
        //写入文字
        $font_col = imagecolorallocatealpha($poster, $color[0], $color[1], $color[2], $color[3]);
        imagettftext($poster, $font_size,0, $config['x'], $config['y'], $font_col, $font_uri, $text);
        return $poster;

    }
/**
 * Notes:去掉名称中的表情
 * @param $str
 * @return string|string[]|null
 * @author: cjhao 2021/3/29 15:56
 */
public function filterEmoji($str)
{
    $str = preg_replace_callback(
        '/./u',
        function (array $match) {
            return strlen($match[0]) >= 4 ? '' : $match[0];
        },
        $str);
    return $str;
}
    public function makeUserMnpQrcode($userinfo,$save_key,$img_src) {
        try {
            $config = cmf_get_option('weipay');
            $wechatC['app_id'] = $config['wx_mini_app_id'];
            $wechatC['secret'] = $config['wx_mini_app_secret'];
            $app = Factory::miniProgram($wechatC);
            $code = $userinfo['distribution_code']; //邀请码
            $response = $app->app_code->get('pages/index/index'.'?invite_code='.$code, [
                'width' => 170,
            ]);
            

            if ($response instanceof \EasyWeChat\Kernel\Http\StreamResponse) {
                $response->saveAs('upload/qr_code/user_share/', $img_src);
                return true;
            }
            if(isset($response['errcode']) && 41030 === $response['errcode']){
                return '商城小程序码,先提交审核并通过';
            }
            return $response['errmsg'];

        } catch (\EasyWeChat\Kernel\Exceptions\Exception $e){
            return $e->getMessage();
        }
    }
    //写入图片
    public function writeImg($poster, $img_uri, $config, $is_rounded = false){
        $pic_img = imagecreatefromstring(file_get_contents($img_uri));
        $is_rounded?$pic_img = self::rounded_corner($pic_img):'';//切成圆角返回头像资源
        $pic_w = imagesx($pic_img);
        $pic_h = imagesy($pic_img);

        //圆形头像大图合并到海报
        imagecopyresampled($poster, $pic_img,
            $config['x'],
            $config['y'],
            0, 0,
            $config['w'],
            $config['h'],
            $pic_w,
            $pic_h
        );

        return $poster;
    }
    /**
 * 将图片切成圆角
 */
public function rounded_corner($src_img)
{
    $w = imagesx($src_img);//微信头像宽度 正方形的
    $h = imagesy($src_img);//微信头像宽度 正方形的
    $w = min($w, $h);
    $h = $w;
    $img = imagecreatetruecolor($w, $h);
    //这一句一定要有
    imagesavealpha($img, true);
    //拾取一个完全透明的颜色,最后一个参数127为全透明
    $bg = imagecolorallocatealpha($img, 255, 255, 255, 127);
    imagefill($img, 0, 0, $bg);
    $r = $w / 2; //圆半径
//    $y_x = $r; //圆心X坐标
//    $y_y = $r; //圆心Y坐标
    for ($x = 0; $x < $w; $x++) {
        for ($y = 0; $y < $h; $y++) {
            $rgbColor = imagecolorat($src_img, $x, $y);
            if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                imagesetpixel($img, $x, $y, $rgbColor);
            }
        }
    }
    unset($src_img);
    return $img;
}

      //用户图片配置
      public function userShareConfig()
      {
          return [
              //会员头像
              'head_pic' => [
                  'w' => 80, 'h' => 80, 'x' => 30, 'y' => 680,
              ],
              //会员昵称
              'nickname' => [
                  'color' => '#333333', 'font_face' => root_path().'public/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'x' => 120, 'y' => 730,
              ],
              //标题
              'title' => [
                  'color' => '#333333', 'font_face' => root_path().'public/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'w' => 360, 'x' => 30, 'y' => 810,
              ],
              //提醒长按扫码
              'notice' => [
                  'color' => '#333333', 'font_face' => root_path().'public/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'x' => 30, 'y' => 880,
              ],
              //邀请码文本
              'code_text' => [
                  'color' => '#FF2C3C', 'font_face' => root_path().'public/font/SourceHanSansCN-Regular.otf', 'font_size' => 20, 'x' => 355, 'y' => 930,
              ],
              //二维码
              'qr' => [
                  'w' => 170,'h' => 170, 'x' => 370, 'y' => 730,
              ],
          ];
      }

最终效果: