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

news2025/1/22 21:38:50

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

 //查询当前用户是否有分销海报
    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,
              ],
          ];
      }

最终效果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1719049.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文搞懂分布式事务-Saga

Saga定义 Saga模式是一种分布式事务处理模式&#xff0c;用于保证分布式系统中的一系列操作要么全部成功执行&#xff0c;要么全部回滚&#xff0c;以实现一致性的目标。它采用了长事务的概念&#xff0c;将原子操作拆分为多个子事务&#xff0c;并通过补偿机制保证整个事务的…

Linux基本命令的使用(mkdir)

一、Linux必备命令之mkdir • mkdir命令主要用于创建目录 • 语法: mkdir [选项] 目录名称 若指定目录不存在则创建目录&#xff1b; 选项&#xff1a; -p&#xff0c;--parents 需要时创建目录的上层目录&#xff0c;若这些 目录已存在也不当作错误处理 二、Linux必备命令之…

成绩发布小程序哪个好用?

大家好&#xff0c;今天我要来跟大家分享一个超级实用的小秘密——易查分小程序&#xff01;作为老师&#xff0c;你是不是还在为发放成绩而头疼&#xff1f;是不是还在为通知家长而烦恼&#xff1f;别急&#xff0c;易查分小程序来帮你啦&#xff01; 易查分简直是老师们的贴心…

实战经验分享之移动云快速部署Stable Diffusion SDXL 1.0

本文目录 前言产品优势部署环境准备模型安装测试运行 前言 移动云是中国移动面向政府、企业和公众的新型资源服务。 客户以购买服务的方式&#xff0c;通过网络快速获取虚 拟计算机、存储、网络等基础设施服务&#xff1b;软件开发工具、运行环境、数据库等平台服务&#xff1…

活动选择问题(贪心法)

目录 问题概述 实例分析 代码实现 问题概述 实例分析 求解蓄栏保留问题。农场有n头牛,每头牛会有一个特定的时间区间[b,e]在蓄栏里挤牛奶,并且一个蓄栏里任何时刻只能有一头牛挤奶。现在农场主希望知道最少蓄栏能够满足上述要求,并给出每头牛被安排的方案。对于多种可行方案…

【算法】贪心算法简介

贪心算法概述 目录 1.贪心算法概念2.贪心算法特点3.贪心算法学习 1.贪心算法概念 贪心算法是一种 “思想” &#xff0c;即解决问题时从 “局部最优” 从而达到 “全局最优” 的效果。 ①把解决问题的过程分为若干步②解决每一步时候&#xff0c;都选择当前最优解(不关注全局…

如何编写一份高质量的渗透测试报告?

随着网络安全威胁的不断扩展与升级&#xff0c; 渗透测试目前已经成为众多组织主动识别安全漏洞与潜在风险的关键过程。然而&#xff0c;渗透测试的真正价值在于为用户提交一份全面和可操作的渗透测试报告&#xff0c;这份报告不仅仅是一个技术性文档&#xff0c;同时也是促进安…

c语言基础:数组的运用以及在内存中的地址的理解

目录 目录&#xff1a; 1.数组作为函数参数 2.数组在内存中的存储 2.1数组名是什么&#xff1f; 2.2下面我们来探讨二维数组的各个名字表示什么 二维数组的首元素地址是什么呢&#xff1f; *arr表示的是什么呢 &#xff1f;&#xff08;arr是二维数组&#xff09; 1.数组作…

纯分享#126个电商平台集合(包含60个不同国家)值得一看

01 亚洲 中国 淘宝&#xff1a;拥有大量的卖家和商品种类&#xff0c;主要面向中国市场。天猫:淘宝旗下的B2C电商平台&#xff0c;提供品质保证、正品保障的商品。京东:中国第二大B2C电商平台&#xff0c;提供品质保证、正品保障的商品。苏宁易购: 中国家电连锁巨头苏宁旗下的…

玩机进阶教程------修改gpt.bin分区表地址段 完全屏蔽系统更新 fast刷写分区表 操作步骤解析【二】

上期博文简单说明了分区表的基本常识。我们在有些环境中需要屏蔽手机的系统更新选项。除了以前博文中说明的修改系统更新下载文件夹的方法。还可以通过修改分区表类达到目的。在一些辅助维修工具上面带修改分区表功能。修改后效果为屏蔽系统更新和可以恢复出厂。原则上不深刷都…

STP----生成树协议

目的&#xff1a;解决二层环路问题 跨层封装 广播风暴---广播帧在二层环路中形成逆时针和顺时针转动环路&#xff0c;并且无限循环&#xff0c;最终造成设备宕机&#xff0c;网络瘫痪。 MAC地址表的翻摆&#xff08;漂移&#xff09;---同一个数据帧&#xff0c;顺时针接收后记…

pytorch学习笔记2

首先如果遇到conda找不到包&#xff0c;pip老是超时的情况建议添加一下镜像源 conda的 conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/ conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/ cond…

将 cuda kernel 编译成 ptx 和 rocm的hip asm

1&#xff0c;cuda 源码编译 cuda_a_one.cu __global__ void NNNNNVVVVV_one(int *A) {A[333] 777; }编译命令&#xff1a; %.ptx: %.cu nvcc -archsm_70 -ptx $< -o $ 生成的结果&#xff1a; 2, hip 源码编译 hip_a_one.hip__global__ void AAAAAMMMMM_one(int *A…

docker安装Mysql5.7版本

首先Linux系统已经安装好了docker应用。 1.搜索镜像 docker search mysql 2.拉取5.7的镜像 总之,选starts最多的那个就对了。 docker pull mysql:5.7 ~ docker pull mysql:5.7 5.7: Pulling from library/mysql fc7181108d40: Downloading [============> …

基于Spring前后端分离版本的论坛系统-自动化测试

目录 前言 一、测试环境 二、环境部署 三、测试用例 四、执行测试 4.1、公共类设计 创建浏览器驱动对象 测试套件 释放驱动类 4.2、功能测试 注册页面 登录页面 版块 帖子 用户个人中心页 站内信 4.3、界面测试 注册页面 登录页面 版块 帖子 用户个人中心页…

Ubuntu基础使用

快捷键&#xff1a; 命令行打开快捷方式&#xff1a;Ctrl Alt T Ctrl l 清屏 截屏&#xff1a; LinuxOS命令&#xff1a; 显示当前工作目录所有内容&#xff1a;ls &#xff08;-a -l、-lh&#xff09; -a 输入全部内容&#xff08;包括隐藏文件&#xff09; -l 竖向展示…

算法每日一题(python,2024.05.26) day.8

题目来源&#xff08;力扣. - 力扣&#xff08;LeetCode&#xff09;&#xff0c;简单&#xff09; 解题思路&#xff1a; 双指针&#xff0b;交换&#xff0c;使用left和right两个指针&#xff0c;right指针向右移动&#xff0c;left从数组首位开始&#xff0c;当right找到非…

【字典树(前缀树) 哈希映射 后序序列化】1948. 删除系统中的重复文件夹

本文涉及知识点 字典树&#xff08;前缀树) 哈希映射 后序序列化 LeetCode 1948. 删除系统中的重复文件夹 由于一个漏洞&#xff0c;文件系统中存在许多重复文件夹。给你一个二维数组 paths&#xff0c;其中 paths[i] 是一个表示文件系统中第 i 个文件夹的绝对路径的数组。 …

Django ORM实战:模型字段与元选项配置,以及链式过滤与QF查询详解

系列文章目录 Django入门全攻略&#xff1a;从零搭建你的第一个Web项目Django ORM入门指南&#xff1a;从概念到实践&#xff0c;掌握模型创建、迁移与视图操作Django ORM实战&#xff1a;模型字段与元选项配置&#xff0c;以及链式过滤与QF查询详解还在写0.0… 文章目录 系列…

Arxiv AI 综述列表(2024.05.27~2024.05.31) VLM

公众号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 每周末更新&#xff0c;完整版进群获取。 Q 群在群文件&#xff0c;VX 群每周末更新。 目录 1. An Introduction to Vision-Language Modeling …