开发完一套餐厅系统后,需要实现生成微信二维码,扫描二维码后公众号弹出图文消息,点击进入系统的功能;二维码还需要与海报图、门店名称和包厢名称拼接;
因为之前开发系统时,就用到了 图片上写入文字功能(GD库),这个功能一样需要用上GD库。
- 生成微信二维码
微信生成的二维码分 永久与 临时两种
$access_token = $this->UpdateToken($wx_id);
$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $access_token;
if ($type == 1) {
//临时二维码
$json = '{"expire_seconds": 2592000, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": ' . $scene_id . '}}}';
} elseif ($type == 2) {
//永久二维码
$json = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": ' . $scene_id . '}}}';
}
$result = json_decode(CurlPost($url, $json), true);
$code_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . urlencode($result['ticket']);
//echo $code_url;
return $code_url;
生成微信二维码具体查看开发文档即可
此时,已经生成了 二维码的链接,但是发现与海报拼接起来尺寸不太对;
微信生成的二维码尺寸为 430×430 但是海报空缺的位置尺寸只有 275×275
需要将图片缩小~
- GD库 图片缩小 主要方法 imagecopyresampled
// 开始查看文档
imagecopyresampled
(PHP 4 >= 4.0.6, PHP 5, PHP 7, PHP 8)
imagecopyresampled — 重采样拷贝部分图像并调整大小
说明
imagecopyresampled(
resource $dst_image,
resource $src_image,
int $dst_x,
int $dst_y,
int $src_x,
int $src_y,
int $dst_w,
int $dst_h,
int $src_w,
int $src_h
):
bool imagecopyresampled() 将一幅图像中的一块正方形区域拷贝到另一个图像中,平滑地插入像素值,因此,尤其是,减小了图像的大小而仍然保持了极大的清晰度。
In other words, imagecopyresampled() will take a rectangular area from src_image of width src_w and height src_h at position (src_x,src_y) and place it in a rectangular area of dst_image of width dst_w and height dst_h at position (dst_x,dst_y).
如果源和目标的宽度和高度不同,则会进行相应的图像收缩和拉伸。坐标指的是左上角。本函数可用来在同一幅图内部拷贝(如果 dst_image 和 src_image 相同的话)区域,但如果区域交迭的话则结果不可预知。
参数
dst_image
目标图象资源。
src_image
源图象资源。
dst_x
目标 X 坐标点。
dst_y
目标 Y 坐标点。
src_x
源的 X 坐标点。
src_y
源的 Y 坐标点。
dst_w
目标宽度。
dst_h
目标高度。
src_w
源图象的宽度。
src_h
源图象的高度。
返回值
成功时返回 true, 或者在失败时返回 false。
封装后的代码 注意设置压缩后图片的长宽 和生成的图片质量
/**
* desription 压缩图片
* @param sting $imgsrc 图片路径
* @param string $imgdst 压缩后保存路径
*/
function compressed_image($imgsrc, $imgdst)
{
list($width, $height, $type) = getimagesize($imgsrc);
// 设置要压缩后图片的长宽
//$new_width = ($width > 600 ? 600 : $width) * 0.9;
$new_width = 275;
//$new_height = ($height > 600 ? 600 : $height) * 0.9;
$new_height = 275;
switch ($type) {
case 1:
$giftype = $this->check_gifcartoon($imgsrc);
if ($giftype) {
header('Content-Type:image/gif');
$image_wp = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromgif($imgsrc);
imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
//75代表的是质量、压缩图片容量大小
imagejpeg($image_wp, $imgdst, 75);
imagedestroy($image_wp);
}
break;
case 2:
header('Content-Type:image/jpeg');
$image_wp = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefromjpeg($imgsrc);
imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
//75代表的是质量、压缩图片容量大小
imagejpeg($image_wp, $imgdst, 75);
imagedestroy($image_wp);
break;
case 3:
header('Content-Type:image/png');
$image_wp = imagecreatetruecolor($new_width, $new_height);
$image = imagecreatefrompng($imgsrc);
imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
//75代表的是质量、压缩图片容量大小
imagejpeg($image_wp, $imgdst, 75);
imagedestroy($image_wp);
break;
}
}
/**
* desription 判断是否gif动画
* @param sting $image_file图片路径
* @return boolean t 是 f 否
*/
function check_gifcartoon($image_file)
{
$fp = fopen($image_file, 'rb');
$image_head = fread($fp, 1024);
fclose($fp);
return preg_match("/" . chr(0x21) . chr(0xff) . chr(0x0b) . 'NETSCAPE2.0' . "/", $image_head) ? false : true;
}
- 二维码与海报图片的拼接
// 二维码
$logo = imagecreatefromjpeg("../public/cust_made/imgs/test.png");
// 海报图
$shirt = imagecreatefrompng("../public/cust_made/imgs/poster.png");
// 定义为透明色 合并图像只能用 merge
imagecolortransparent($logo, imagecolorat($logo, 0, 0));
$logo_x = imagesx($logo);
$logo_y = imagesy($logo);
imagecopymerge($shirt, $logo, 167, 360, 0, 0, $logo_x, $logo_y, 100);
注意用到 imagecolortransparent 方法后 只能使用 imagecopymerge 而不是 imagecopy
此时可以直接输出查看,二维码与海报图片已拼接完毕
//header('Content-Type: image/png');
//imagepng($shirt);
//$data = ob_get_contents();
//ob_end_clean();
//$base_data = "data:image/jpeg;base64," . base64_encode($data);
//imagedestroy($shirt); // 销毁图片
//return json(['data' => $base_data]);
- 拼接 门店名称 和 包厢的名称 到图片上
// 拼接 门店名称和包厢名称
$font = '您的字体路径/您的字体文件.ttf';
$font = realpath($font);
$color = "#91161c"; // 字体颜色
$colorRgb = self::hex2rgb($color); // 需要 16进制转 RGB
$color = imagecolorallocate($shirt, $colorRgb[0], $colorRgb[1], $colorRgb[2]);
$title = "感谢你、你真帅"; // 写的啥文字自定义
$font_size = 26;
$font_size_pounds = round($font_size / (96 / 72), 1);
写字的方法来咯
写字的方法来咯 此方法已经封装好 文字 横竖写法 和 文字的字体间距 可自行调整
$this->imagettftextSp($shirt,$font_size_pounds,0,215,675,$color, $font, $title, 1,0);
header('Content-Type: image/png');
imagepng($shirt);
$data = ob_get_contents();
ob_end_clean();
$base_data = "data:image/jpeg;base64," . base64_encode($data);
imagedestroy($shirt); // 销毁图片
return json(['data' => $base_data]);
最后输出的格式为 base64 实际后面使用了base64 上传到本地服务器返回图片地址
/**
* phpgd库图片绘制文字横竖写法和间距
* @param string $position 1横2竖
* @param string $spacing 字体间距
* @return array
*/
function imagettftextSp($image, $size, $angle, $x, $y, $color, $font, $text, $position, $spacing = 0)
{
if ($position == 1) {
// 横写
if ($spacing == 0) {
imagettftext($image, $size, $angle, $x, $y, $color, $font, $text);
} else {
$temp_x = $x;
for ($i = 0; $i < strlen($text); $i++) {
$bbox = imagettftext($image, $size, $angle, $temp_x, $y, $color, $font, mb_substr($text, $i, 1, 'utf-8'));
$temp_x += $spacing + ($bbox[2] - $bbox[0]);
}
}
} elseif ($position == 2) {
// 竖写
$temp_y = $y;
for ($i = 0; $i < strlen($text); $i++) {
$bbox = imagettftext($image, $size, $angle, $x, $temp_y, $color, $font, mb_substr($text, $i, 1, 'utf-8'));
$temp_y += $spacing + ($bbox[1] - $bbox[7]);
}
}
}
/**
* 十六进制转RGB
* @param string $color 16进制颜色值
* @return array
*/
public static function hex2rgb($color)
{
$hexColor = str_replace('#', '', $color);
$lens = strlen($hexColor);
if ($lens != 3 && $lens != 6) {
return false;
}
$newcolor = '';
if ($lens == 3) {
for ($i = 0; $i < $lens; $i++) {
$newcolor .= $hexColor[$i] . $hexColor[$i];
}
} else {
$newcolor = $hexColor;
}
$hex = str_split($newcolor, 2);
$rgb = [];
foreach ($hex as $key => $vls) {
$rgb[] = hexdec($vls);
}
return $rgb;
}
最后生成的这张海报,就可以打印贴在包厢桌上,扫码后 公众号返回图文消息等等,就跟GD库没有关系了; 最后来一张成品图片 海报内容涉嫌机密马赛克处理 . . . . . .