zoukankan      html  css  js  c++  java
  • php实现自定义中间logo的微信小程序码

    小程序码生成的时候是默认使用小程序后台设置的小程序icon图片的,但是在有些场景我们可能要替换成我们自己想要的icon。
    下面先放代码:

    public function makeNewQrCodeAction()
        {
            //获取用户头像并转string
            $avatarUrl = $this->_req->getQuery('avatarUrl', "");
            if (!$avatarUrl) {
                response::err_lack_param();
            }
            $avatar_file = file_get_contents($avatarUrl);
            $logo = $this->changeAvatar($avatar_file);
    
            //获取小程序码
            $data['scene'] = $this->_req->getQuery('code', 1); 
            $data['width'] = (int)$this->_req->getQuery('width', 280);
            $data['auto_color'] = $this->_req->getQuery('auto_color');
            $data['line_color'] = $this->_req->getQuery('line_color');   //看了很多人说设置线条颜色失败,我也尝试了下,发现失败可能存在这两个原因其一:1、没有设置auto_color的值为true;2、设置的颜色微信还不支持。我尝试的rgb(255,0,0)是可以的,但是rgb(0,255,0)就不支持了。所以遇到设置线条颜色无效的可以先设置rgb(255,0,0)看看先
            $data['is_hyaline'] = $this->_req->getQuery('is_hyaline');  //设置二维码底色是否透明,默认false
            $data['page'] = $this->_req->getQuery('path');
            $wxModel = new HdWxAuthModel();
            $Qr_code = $wxModel->getShareCode($data);  //生成小程序码接口
            
           //        file_put_contents('/tmp/tmp_qr.png',$Qr_code); exit; //这里先看一下生成的小程序码是否是自己设置的格式
    
            //小程序码与头像进行拼接
            $url = $this->makeOnePic($Qr_code, $logo); 
            response::result($url);
    
        }
    
    
        private function  makeOnePic($qr_code, $logo)  //二维码与头像组合
        {
            $qr_code = imagecreatefromstring($qr_code);  //生成的二维码底色为白色
    
            //设置二维码为透明底
             imagesavealpha($qr_code, true);  //这个设置一定要加上
            $bg = imagecolorallocatealpha($qr_code, 255, 255, 255, 127);   //拾取一个完全透明的颜色,最后一个参数127为全透明
            imagefill($qr_code, 0, 0, $bg);
    
            $icon = imagecreatefromstring($logo);  //生成中间圆形logo (微信头像获取到的logo的大小为132px 132px)
    
            $qr_width = imagesx($qr_code);  //二维码图片宽度
    //        $qr_height = imagesy($qr_code);  //二维码图片高度
            $lg_width = imagesx($icon);  //logo图片宽度
            $lg_height = imagesy($icon);  //logo图片高度
    
    //        var_dump($qr_width,$qr_height);
    //        var_dump($lg_width,$lg_height);
    
            $qr_lg_width = $qr_width / 2.2;
            $scale = $lg_width / $qr_lg_width;
            $qr_lg_height = $lg_height / $scale;
    
            $start_width = ($qr_width - $lg_width) / 2 + 2;  //(获取logo的左上方的位置:( 外部的正方形-logo的宽 ) / 2,我这边存在1px的偏差 我就给+2啦)
    //        var_dump($scale,$qr_lg_height);
    //        var_dump($start_width);
            imagecopyresampled($qr_code, $icon, $start_width, $start_width, 0, 0, $qr_lg_width, $qr_lg_height, $lg_width, $lg_height);
    
            //传回处理好的图片url
    //        $qrcode = "/imgs/qrCode" . time() . ".png";
    
    
    
    //        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    //        $tmp_url = $protocol . $_SERVER['HTTP_HOST'] . $qrcode;  //LCT这个需上线后除去
    //        response::result($tmp_url);
    
            imagepng($qr_code); //保存
            imagedestroy($qr_code);
            imagedestroy($icon);
            exit;
        }
    
    
        private function changeAvatar($avatar)  
        { 
           //处理用户头像为圆形icon
            $avatar = imagecreatefromstring($avatar);
            $w = imagesx($avatar);
            $h = imagesy($avatar);
            $w = min($w, $h);
            $h = $w;
    
            $img = imagecreatetruecolor($w, $h);
            imagesavealpha($img, true);
            $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($avatar, $x, $y);
    
                    if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
                        imagesetpixel($img, $x, $y, $rgbColor);
                    }
                }
            }
    
            ob_start();  
            imagepng($img);
            imagedestroy($img);
            imagedestroy($avatar);
            $contents = ob_get_contents();  、、读取缓存区的内容
            ob_end_clean();  //清空缓存区
    
            return $contents;
        }
    
    
       public function getShareCode($data)  //生成小程序码
       {
            $access_token = $this->getAccessToken();  //获取access_token这个要设置token缓存,具体可以查看我的另一篇文章
            $res_url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=$access_token";
            header('content-type:image/png');
            $data = json_encode($data);
            $Qr_code = $this->http_request($res_url, $data);
            return $Qr_code;
    
        }
    
    
    

    遇到的困难:

    *之前将头像图片、处理成圆形头像的图片及最后的组合图都先生成本地图片,然后再处理,这样就多了一个图片存放的问题,在用户很多的时候可能会产生很多不需要的图。

    *要求最终生成的二维码为透明的底,一般来说是在生成二维码的时候设置is_hyaline=true就可以了,但是我们这里再次对二维码数据流进行再次生成,imagecreatefromstring()默认生成的为白色底,这样就让生成的透明底二维码又带了白色底。一直以为微信的is_hyaline配置无效。( T _ T )

    存在的问题:

    最后生成的二维码中间的icon可能会出现位置不居中的问题。这个我这边设置大小width大小为280左右的时候就大概能看。应该是算icon图位置的时候没有设好。这个有空要重新来一遍。


    *** 突发bug: 未设置头像的微信用户 得到的二维码为空白图 (新申请的微信账号一开始是无头像的,哈哈哈这操作,我无知了~)
    解决方式:
    2019-03-22更新:

    public function makeNewQrCodeAction()
    {
    //获取用户头像并转string
    $avatarUrl = $this->_req->getQuery('avatarUrl', "");
    // if (!$avatarUrl) {
    // response::err_lack_param();
    //}
    if (!$avatarUrl) {
    $avatarUrl = file_get_content(APP_PATH . "/public/imgs/default.png"); //这边如果微信用户没有设置头像,给一个默认的头像,不然得到的二维码是空白图。
    }
    $avatar_file = file_get_contents($avatarUrl);
    $logo = $this->changeAvatar($avatar_file);

        //获取小程序码
        $data['scene'] = $this->_req->getQuery('code', 1); 
        $data['width'] = (int)$this->_req->getQuery('width', 280);
        $data['auto_color'] = $this->_req->getQuery('auto_color');
        $data['line_color'] = $this->_req->getQuery('line_color');   //看了很多人说设置线条颜色失败,我也尝试了下,发现失败可能存在这两个原因其一:1、没有设置auto_color的值为true;2、设置的颜色微信还不支持。我尝试的rgb(255,0,0)是可以的,但是rgb(0,255,0)就不支持了。所以遇到设置线条颜色无效的可以先设置rgb(255,0,0)看看先
        $data['is_hyaline'] = $this->_req->getQuery('is_hyaline');  //设置二维码底色是否透明,默认false
        $data['page'] = $this->_req->getQuery('path');
        $wxModel = new HdWxAuthModel();
        $Qr_code = $wxModel->getShareCode($data);  //生成小程序码接口
        
       //        file_put_contents('/tmp/tmp_qr.png',$Qr_code); exit; //这里先看一下生成的小程序码是否是自己设置的格式
    
        //小程序码与头像进行拼接
        $url = $this->makeOnePic($Qr_code, $logo); 
        response::result($url);
    
    }
    

    再次更新:
    遇到的问题:组合得到的小程序码有时会出现是空白。查看错误日志发现出现40001错误。
    原因:开发环境的小程序appid和appsecret的账号跟线上环境的账号是一样的,生成小程序码请求到的token存在两个不同的服务器。当某个环境的token被更新的时候,另一个环境的token虽然在缓存时间内,但是由于跟服务器的token不一致了,就会出现过期的现象。(这个真的得注意,一个小程序应该使用同一个token,保证拿到的token是最新的)
    解决思路:
    1、开发环境、测试环境及线上环境应该用不同的appid账号,避免请求微信token的时候存在冲突;
    2、多个环境的token存在同一个文件里,采用接口来获取最新的token;同一个token过期会重新请求,所以能避免拿到过期token。

    微信接口有时还会出现不稳定的时候,一定要做好异常处理。
  • 相关阅读:
    卸载驱动时,没有/lib/modules目录
    strcmp与strncmp的区别
    12864 显示多种图形
    环形缓冲区的应用ringbuffer
    环形缓冲区
    pthread_cond_wait 详解
    [置顶] 自己写一个简单通用的Makefile
    指针空间的申请与释放
    双向链表操作
    FreeType 管理字形
  • 原文地址:https://www.cnblogs.com/xinxinmifan/p/weixinlogo.html
Copyright © 2011-2022 走看看