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