综述
项目开发中需求,要求在APP中进行分享的时候可以分享图片,图片由美工进行设计,其上带有二维码,分享给别人可以直接长按图片进行识别。这种方式在分享中用户体验更好,首先图片由美工设计很好看,其次这种方式比单单的分享出去一个链接更能吸引人。总之将实现过程进行记录。
准备
首先要美工设计的分享海报效果图,根据海报效果图标注获取图片模板(如下所示)。
代码
<?php
/**
* =======================================
* Created by ZHIHUA·WEI.
* Author: ZHIHUA·WEI
* Date: 2019/03/21
* Time: 20:13
* Power: PHP生成带二维码的分享图片
* =======================================
*/
/**
* 主函数1:生成带二维码的分享图片
* @return array
*/
function createSharePicWithQrCode()
{
//1、获得根目录|声明图片上的分享人信息(可从数据库中获取,根据需求进行)
$root_dir = $_SERVER['DOCUMENT_ROOT'];
$user_info = array(
'uid' => 1,
'user_name' => '开发人员',
'user_tel' => '18000000001',
'user_headimg' => '/uploads/default_user_portrait.gif'
);
//2、生成分享二维码|定义构造二维码地址,大小,logo图
createShareQrCode($user_info, $root_dir);
//3、生成分享图片|并上传到七牛云|将结果存入数据库
$share_pic_folder = '/uploads/share_profit/share_image/';
$share_pic_data = createSharePic($user_info, $root_dir, $share_pic_folder);
//4、到此进本生成完毕,下面就是进行各种数据逻辑处理返回等,可按照自己需求进行编写
return $share_pic_data;
}
/**
* 辅助函数1:生成二维码图片
* @param $user_info
* @param $root_dir
*/
function createShareQrCode($user_info, $root_dir)
{
//1.1、获得用户头像地址
$logo_dir = $root_dir . $user_info['user_headimg'];
//1.2、构造生成二维码图片数据信息(由于可能同时需要生成多个分享图片,故可能需要多个不同的二维码)
//此种情况可根据需求而定(博主将此处定义成数组就是同时生成了四个分享海报,博文只取其中一个进行演示)
$down_url = 'http://share.zhihuawei.cn';
$share_qr_date = array(
[
'url' => $down_url . '/paike.html?mobile=' . $user_info['user_tel'],//生成二维码包含地址
'qr_code_name' => $user_info['uid'] . '_' . $user_info['user_tel'] . '_1',//生成二维码名称(可根据自己习惯进行明描)
'point_size' => 4,//二维码大小设置
],
[
'url' => $down_url . '/look.html?mobile=' . $user_info['user_tel'],
'qr_code_name' => $user_info['uid'] . '_' . $user_info['user_tel'] . '_2',
'point_size' => 4,
],
);
//1.3、生成二维码(如果是多个的话进行循环生成)
foreach ($share_qr_date as $item) {
qrCodeWithLogo($root_dir, $item['url'], $item['qr_code_name'], $logo_dir, $item['point_size']);
}
}
/**
* 辅助函数2:生成带Logo的二维码
* @param $root_dir
* @param $url
* @param $qr_code_name
* @param $logo_dir
* @param int $point_size
*/
function qrCodeWithLogo($root_dir, $url, $qr_code_name, $logo_dir, $point_size = 4)
{
//2.1、引入生成二维码代码库(此处使用的是phpqrcode)|实例化对象
require_once $_SERVER['DOCUMENT_ROOT'] . '/vendor/phpqrcode/phpqrcode.php';
$object = new \QRcode();
//2.2、声明二维码存放路径|且先判断文件目录是否存在,不存在则创建
$base_qr_code_path = $root_dir . "/uploads/share/share_qrcode/";
$base_qr_code_logo_path = $root_dir . "/uploads/share/share_qrcode_logo/";
if (!file_exists($base_qr_code_path)) {
mkdir($base_qr_code_path, 0777, true);
}
if (!file_exists($base_qr_code_logo_path)) {
mkdir($base_qr_code_logo_path, 0777, true);
}
//2.3、首先生成不带Logo的二维码
//2.3.1、声明定义二维码存在地址路径
$qr_code_dir = $base_qr_code_path . $qr_code_name . ".png";
//2.3.2、生成一个二维码图片
$object->png($url, $qr_code_dir, 'L', $point_size, 2);
//2.4、生成带Logo的二维码
//2.4.1、获得已经生成的原始二维码图|获得Logo地址(使用的是会员头像,也可根据需求定义使用其他的)
$qr_code = imagecreatefromstring(file_get_contents($qr_code_dir));
$logo = imagecreatefromstring(file_get_contents($logo_dir));
//2.4.2、获得二维码宽度、高度(一般一样,获取一个即可)|获取Logo宽度、高度
$qr_code_width = imagesx($qr_code); //二维码图片宽度
//$qr_code_height = imagesy($qr_code); //二维码图片高度
$logo_width = imagesx($logo); //logo图片宽度
$logo_height = imagesy($logo); //logo图片高度
//2.4.3、进行计算Logo的放置位置(放于中间位置)
$logo_qr_width = $qr_code_width / 5;
$scale = $logo_width / $logo_qr_width;
$logo_qr_height = $logo_height / $scale;
$from_width = ($qr_code_width - $logo_qr_width) / 2;
//2.4.4、重新组合图片并调整大小
imagecopyresampled($qr_code, $logo, $from_width, $from_width, 0, 0, $logo_qr_width,
$logo_qr_height, $logo_width, $logo_height);
//2.4.5、输出带Logo的二维码图片|二维码图片
$qr_code_logo_name = $qr_code_name . '_logo';
$qr_code_logo_dir = $base_qr_code_logo_path . $qr_code_logo_name . ".png";
imagepng($qr_code, $qr_code_logo_dir);
}
/**
* 辅助函数3:生成带二维码的分享海报图片
* @param $user_info
* @param $root_dir
* @param $share_pic_folder
* @return array
*/
function createSharePic($user_info, $root_dir, $share_pic_folder)
{
//3.1、字体文件
$font_file_bold = $root_dir . '/fonts/PingFang_Bold.ttf';
//3.2、判断存放分享海报的文件夹是否存在,如不存在则创建文件夹
$share_pic_dir = $root_dir . $share_pic_folder;
if (!file_exists($share_pic_dir)) {
mkdir($share_pic_dir, 0777, true);
}
//3.3、构造海报图片数据(可根据)|定义返回数据(一些二维码的名称命名,海报模板命名,生成海报图片命名最好设置一定的命名规则)
$share_profit_img_data = array(
[
'user_name' => '邀请人:' . $user_info['user_name'],//邀请人名称(会员名称)
'user_tel' => '(' . $user_info['user_tel'] . ')',//邀请人电话(会员手机号)
'share_tpl_pic' => $root_dir . '/public/share_tpl/share_tpl_1.png',//海报模板图
'tpl_type' => 1,//模板类型
'sort' => 1,//排序值
'qr_code_logo_dir' => $root_dir . '/uploads/share/share_qrcode_logo/' . $user_info['uid'] . '_' . $user_info['user_tel'] . '_1_logo.png',//带logo的二维码图片
'qr_code_dir' => $root_dir . '/uploads/share/share_qrcode/' . $user_info['uid'] . '_' . $user_info['user_tel'] . '_1.png',//不带logo的二维码图片(暂无用)
'share_pic_name' => $user_info['uid'] . '_' . $user_info['user_tel'] . '_1.png',//生成海报名称
],
[
'user_name' => '邀请人:' . $user_info['user_name'],
'user_tel' => '(' . $user_info['user_tel'] . ')',
'share_tpl_pic' => $root_dir . '/public/share_tpl/share_tpl_2.png',
'tpl_type' => 2,
'sort' => 2,
'qr_code_logo_dir' => $root_dir . '/uploads/share/share_qrcode_logo/' . $user_info['uid'] . '_' . $user_info['user_tel'] . '_2_logo.png',
'qr_code_dir' => $root_dir . '/uploads/share/share_qrcode/' . $user_info['uid'] . '_' . $user_info['user_tel'] . '_2.png',
'share_pic_name' => $user_info['uid'] . '_' . $user_info['user_tel'] . '_2.png',
]
);
$ret_data = array();
//3.4、进行循环创建海报图片
foreach ($share_profit_img_data as $item) {
//3.4.1、创建画布
$im = imagecreatetruecolor(750, 1334);
//3.4.2、填充画布背景色
$background_color = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 0, 0, $background_color);
//3.4.3、设定字体的颜色(不同的字体颜色可设置多种颜色)
//$font_color_1 = imagecolorallocate($im, 0, 0, 0);
$font_color_2 = imagecolorallocate($im, 255, 255, 255);
//3.4.4、分享赚海报图片模板|获得其宽高
list($tpl_w, $tpl_h) = getimagesize($item['share_tpl_pic']);
//3.4.5、载入海报模板图片资源(必须是PNG格式)
$share_tpl_pic = @imagecreatefrompng($item['share_tpl_pic']);
//3.4.6、将分享赚海报模板图片放置于画布上,全覆盖方式放置(海报模板规格采用的是750*1334,这个可按照个人需求)
@imagecopyresized($im, $share_tpl_pic, 0, 0, 0, 0, 750, 1334, $tpl_w, $tpl_h);
//3.4.7、判断海报模板类型,进行二维码图片放置、描述文字放置
//载入二维码图片资源(必须是PNG格式)|获得二维码的宽高(暂不进行判断带logo二维码是否存在)
$qr_code_logo_pic = @imagecreatefrompng($item['qr_code_logo_dir']);
list($qr_code_w, $qr_code_h) = getimagesize($item['qr_code_logo_dir']);
//3.5、根据不同的模板类型将二维码一级文字放置到不同的位置(适用于海报模板较多情况,如果只有一种可自行修改代码即可)
if ($item['tpl_type'] == 1) {
//3.5.1、将二维码图片放置于画布上
@imagecopyresized($im, $qr_code_logo_pic, 275, 652, 0, 0, 200, 200, $qr_code_w, $qr_code_h);
//3.5.2、文字水平居中实现
$font_box_tmp1 = imagettfbbox(20, 0, $font_file_bold, $item['user_name'] . $item['user_tel']);
//3.5.3、将文字放置图片上
imagettftext($im, 20, 0, ceil(($tpl_w - $font_box_tmp1[2]) / 2), 895, $font_color_2, $font_file_bold, $item['user_name'] . $item['user_tel']);
//3.5.4、实现加粗效果将文字平移一个像素再写入一次
imagettftext($im, 20, 0, ceil(($tpl_w - $font_box_tmp1[2]) / 2) + 1, 895, $font_color_2, $font_file_bold, $item['user_name'] . $item['user_tel']);
$font_box_tmp2 = imagettfbbox(20, 0, $font_file_bold, '长按图片识别二维码了解');
imagettftext($im, 20, 0, ceil(($tpl_w - $font_box_tmp2[2]) / 2), 935, $font_color_2, $font_file_bold, '长按图片识别二维码了解');
imagettftext($im, 20, 0, ceil(($tpl_w - $font_box_tmp2[2]) / 2) + 1, 935, $font_color_2, $font_file_bold, '长按图片识别二维码了解');
} elseif ($item['tpl_type'] == 2) {
@imagecopyresized($im, $qr_code_logo_pic, 363, 328, 0, 0, 140, 140, $qr_code_w, $qr_code_h);
//3.5.5、进行自定义位置放置,这种情况就是按照设计人员出的设计图进行调整了
$str_len = iconv_strlen($item['user_name'], "UTF-8");
if ($str_len > 8) {
$invite = mb_substr($item['user_name'], 0, 8, "UTF-8");
$invite = $invite . '...';
} else {
$invite = $item['user_name'];
}
imagettftext($im, 16, 0, 350, 510, $font_color_2, $font_file_bold, $invite);
imagettftext($im, 16, 0, 355, 540, $font_color_2, $font_file_bold, $item['user_tel']);
imagettftext($im, 16, 0, 372, 580, $font_color_2, $font_file_bold, "长按图片识别");
imagettftext($im, 16, 0, 373, 580, $font_color_2, $font_file_bold, "长按图片识别");
imagettftext($im, 16, 0, 380, 605, $font_color_2, $font_file_bold, "二维码了解");
imagettftext($im, 16, 0, 381, 605, $font_color_2, $font_file_bold, "二维码了解");
}
//3.6、输出海报图片保存到服务器
imagepng($im, $share_pic_dir . $item['share_pic_name']);
//3.7、释放空间
@imagedestroy($im);
@imagedestroy($share_tpl_pic);
@imagedestroy($qr_code_logo_pic);
//3.8、也可将图片上传到各种云存储(例如:七牛云等)
//$qiniu = new Qiniu();
//$share_img_qiniu = $qiniu->uploadFile($share_pic_dir . $item['share_pic_name']);
$share_img_qiniu = '';
//3.9、构造返回数据
$ret_data[] = array(
'uid' => $user_info['uid'],
'share_img' => $share_pic_folder . $item['share_pic_name'],
'share_img_qiniu' => $share_img_qiniu,
'sort' => $item['sort'],
'qrcode_url' => '/uploads/share/share_qrcode_logo/' . $user_info['uid'] . '_' . $user_info['user_tel'] . '_' . $item['tpl_type'] . '_logo.png',
'create_time' => date("Y-m-d H:i:s"),
);
}
return $ret_data;
}
效果
上面三张都是生成的效果图,欢迎大家相互学习。