php生产自定义logo图的二维码

这篇博客详细介绍了如何在PHP中生成带有用户头像且底色透明的小程序码。首先,从请求中获取用户头像并转换为圆形图标,然后调用微信接口获取小程序码,再将两者结合。过程中遇到了头像缺失导致空白图的bug,通过设置默认头像解决了此问题。同时,还讨论了二维码线条颜色设置和位置调整等技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

public function makeNewQrCodeAction()
{
//获取用户头像并转string
$avatarUrl = t h i s − > r e q − > g e t Q u e r y ( ′ a v a t a r U r l ′ , " " ) ; i f ( ! this->_req->getQuery('avatarUrl', ""); if (! this>req>getQuery(avatarUrl,"");if(!avatarUrl) {
response::err_lack_param();
}
a v a t a r f i l e = f i l e g e t c o n t e n t s ( avatar_file = file_get_contents( avatarfile=filegetcontents(avatarUrl);
$logo = t h i s − > c h a n g e A v a t a r ( this->changeAvatar( 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 \Hd\WxAuthModel();
    $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);  //二维码图片宽度

// q r h e i g h t = i m a g e s y ( qr_height = imagesy( qrheight=imagesy(qr_code); //二维码图片高度
l g w i d t h = i m a g e s x ( lg_width = imagesx( lgwidth=imagesx(icon); //logo图片宽度
l g h e i g h t = i m a g e s y ( lg_height = imagesy( lgheight=imagesy(icon); //logo图片高度

// var_dump( q r w i d t h , qr_width, qrwidth,qr_height);
// var_dump( l g w i d t h , lg_width, lgwidth,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( s c a l e , scale, scale,qr_lg_height);
// var_dump( s t a r t w i d t h ) ; i m a g e c o p y r e s a m p l e d ( start_width); imagecopyresampled( startwidth);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”;

// p r o t o c o l = ( ! e m p t y ( protocol = (!empty( protocol=(!empty(_SERVER[‘HTTPS’]) && $_SERVER[‘HTTPS’] !== ‘off’ || $_SERVER[‘SERVER_PORT’] == 443) ? “https://” : “http://”;
// $tmp_url = $protocol . $_SERVER[‘HTTP_HOST’] . q r c o d e ; / / L C T 这 个 需 上 线 后 除 去 / / r e s p o n s e : : r e s u l t ( qrcode; //LCT这个需上线后除去 // response::result( 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缓存,具体可以查看我的另一篇文章
r e s u r l = " h t t p s : / / a p i . w e i x i n . q q . c o m / w x a / g e t w x a c o d e u n l i m i t ? a c c e s s t o k e n = res_url = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token= resurl="https://api.weixin.qq.com/wxa/getwxacodeunlimit?accesstoken=access_token";
header(‘content-type:image/png’);
d a t a = j s o n e n c o d e ( data = json_encode( data=jsonencode(data);
$Qr_code = t h i s − > h t t p r e q u e s t ( this->http_request( this>httprequest(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 = t h i s − > r e q − > g e t Q u e r y ( ′ a v a t a r U r l ′ , " " ) ; / / i f ( ! this->_req->getQuery('avatarUrl', ""); // if (! this>req>getQuery(avatarUrl,"");//if(!avatarUrl) {
// response::err_lack_param();
//}
if (!$avatarUrl) {
$avatarUrl = file_get_content(APP_PATH . “/public/imgs/default.png”); //这边如果微信用户没有设置头像,给一个默认的头像,不然得到的二维码是空白图。
}
a v a t a r f i l e = f i l e g e t c o n t e n t s ( avatar_file = file_get_contents( avatarfile=filegetcontents(avatarUrl);
$logo = t h i s − > c h a n g e A v a t a r ( this->changeAvatar( 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 \Hd\WxAuthModel();
$Qr_code = $wxModel->getShareCode($data);  //生成小程序码接口

// file_put_contents(’/tmp/tmp_qr.png’,$Qr_code); exit; //这里先看一下生成的小程序码是否是自己设置的格式

//小程序码与头像进行拼接
$url = $this->makeOnePic($Qr_code, $logo); 
response::result($url);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值