问题描述:
用php生成海报,海报里面有背景图,二维码、头像、昵称。
头像是圆角的。
解决办法:
//生成海报
public function createhaibao(Request $req){
$newqrcode=new WxMiniProgramController();
$scene=$req->qr;// pages/active/greeting-card/greeting-card?id=17&isLogin=0
$nickname=$req->nickname;//昵称
$uuid=$req->uuid;//uuid
$avatar=$req->avatar;//微信头像
$scenearr=explode('?', $scene);
// 将base64字符串转换为图片二维码
$qrcode=$newqrcode->getzhongqiuqrCode($scenearr[0],$scenearr[1],$siteId='');
file_put_contents('/api//public/upload/zhongqiuhaibao/'.$uuid.'_qrcode.jpg', base64_decode(str_replace('data:image/jpeg;base64,', '', $qrcode)));
//把微信头像转存本地 /upload/zhongqiuhaibao/tou1.jpeg
$tou=$this->download_remote_pic($avatar,'/upload/zhongqiuhaibao',$uuid);
//把微信头像设置成圆角
$imgg = $this->radius_img('/api//gtzy_app/public'.$tou, 220);
imagepng($imgg,'/api//gtzy_app/public/upload/zhongqiuhaibao/'.$uuid.'_tou.jpeg');
imagedestroy($imgg);
$config = array(
'text'=>array(
array(
'text'=>$nickname,//方框??
'left'=>200,
'top'=>-340,
'fontPath'=>'/api/gtzy_app_temp/gtzy_app/public/upload/zhongqiuhaibao/msyh.ttc', //字体文件
'fontSize'=>18, //字号
'fontColor'=>'255,40,20', //字体颜色
'angle'=>0,
)
),
'image'=>array(
array(
'url'=>'/api/gtzy_app_temp/gtzy_app/public/upload/zhongqiuhaibao/'.$uuid.'_qrcode.jpg', //二维码图片资源路径
'left'=>45,
'top'=>-70,
'stream'=>0, //图片资源是否是字符串图像流
'right'=>0,
'bottom'=>0,
'width'=>120,
'height'=>120,
'opacity'=>100
),
array(
'url'=>'/api/gtzy_app_temp/gtzy_app/public/upload/zhongqiuhaibao/'.$uuid.'_tou.jpeg',
'left'=>70,
'top'=>-260,
'right'=>0,
'stream'=>0,
'bottom'=>0,
'width'=>100,
'height'=>100,
'opacity'=>100
),
),
'background'=>'/api/gtzy_app_temp/gtzy_app/public/upload/zhongqiuhaibao/background.jpg',
);
$filename = '/api/gtzy_app_temp/gtzy_app/public/upload/zhongqiuhaibao/'.$uuid.'_haibao.jpg';
//echo createPoster($config,$filename);
$a=$this->createPoster($config,$filename);
$refile=substr($filename, 34);
$httpfile="https://cyx.gtzyc.com".$refile;
return response()->json(['result' => 1, 'msg' => '生成海报成功','file'=>$httpfile]);
}
/**
* 生成宣传海报图片
* @param array 参数,包括图片和文字
* @param string $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
* @return [type] [description]
*/
public function createPoster($config=array(),$filename=""){
//如果要看报什么错,可以先注释调这个header
if(empty($filename)) header("content-type: image/png");
$imageDefault = array(
'left'=>0,
'top'=>0,
'right'=>0,
'bottom'=>0,
'width'=>100,
'height'=>100,
'opacity'=>100
);
$textDefault = array(
'text'=>'',
'left'=>0,
'top'=>0,
'fontSize'=>32, //字号
'fontColor'=>'255,255,255', //字体颜色
'angle'=>0,
);
$background = $config['background'];//海报最底层得背景
//背景方法
$backgroundInfo = getimagesize($background);
$backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false);
$background = $backgroundFun($background);
$backgroundWidth = imagesx($background); //背景宽度
$backgroundHeight = imagesy($background); //背景高度
$imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight);
$color = imagecolorallocate($imageRes, 0, 0, 0);
imagefill($imageRes, 0, 0, $color);
// imageColorTransparent($imageRes, $color); //颜色透明
imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background));
//处理图片
if(!empty($config['image'])){
foreach ($config['image'] as $key => $val) {
$val = array_merge($imageDefault,$val);
$info = getimagesize($val['url']);
$function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
if($val['stream']){ //如果传的是字符串图像流
$info = getimagesizefromstring($val['url']);
$function = 'imagecreatefromstring';
}
$res = $function($val['url']);
$resWidth = $info[0];
$resHeight = $info[1];
//建立画板 ,缩放图片至指定尺寸
$canvas=imagecreatetruecolor($val['width'], $val['height']);
imagefill($canvas, 0, 0, $color);
//关键函数,参数(目标资源,源,目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h)
imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
$val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
//放置图像
imagecopymerge($imageRes,$canvas, $val['left'],$val['top'],$val['right'],$val['bottom'],$val['width'],$val['height'],$val['opacity']);//左,上,右,下,宽度,高度,透明度
}
}
//处理文字
if(!empty($config['text'])){
foreach ($config['text'] as $key => $val) {
$val = array_merge($textDefault,$val);
list($R,$G,$B) = explode(',', $val['fontColor']);
$fontColor = imagecolorallocate($imageRes, $R, $G, $B);
$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
$val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
$nicknames= $this->removeEmojiChar($val['text']);
imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$nicknames);
}
}
//生成图片
if(!empty($filename)){
$res = imagejpeg ($imageRes,$filename,90); //保存到本地
imagedestroy($imageRes);
if(!$res) return false;
return $filename;
}else{
imagejpeg ($imageRes); //在浏览器上显示
imagedestroy($imageRes);
}
}
//移除微信表情
public function removeEmojiChar($str){
$mbLen = mb_strlen($str);
$strArr = [];
for ($i = 0; $i < $mbLen; $i++) {
$mbSubstr = mb_substr($str, $i, 1, 'utf-8');
if (strlen($mbSubstr) >= 4) {
continue;
}
$strArr[] = $mbSubstr;
}
return implode('', $strArr);
}
/* PHP远程下载微信头像存到本地,本地图片转base64
* $url 微信头像链接
* $path 要保存图片的目录
* $userid 用户唯一标识(用这个作为图片文件名,可以节省图片空间)
*/
public function download_remote_pic($url,$path,$userid){
$header = [
'User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:45.0) Gecko/20100101 Firefox/45.0',
'Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding: gzip, deflate',
];
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
if (substr($url, 0, 5) == 'https') {
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
}
$data = curl_exec($curl);
if($error=curl_error($curl)){
return response()->json(['result' => -1, 'msg' => $error]);
}
$code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
curl_close($curl);
//把URL格式的图片转成base64_encode格式的!
$imgBase64Code = "data:image/jpeg;base64," . base64_encode($data);
$img_content=$imgBase64Code;//图片内容
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $img_content, $result)) {
$type = $result[2];//得到图片类型png jpg gif
//相对路径
$relative_path=$path."/";
//绝对路径($_SERVER['DOCUMENT_ROOT']为网站根目录)
$absolute_path = $_SERVER['DOCUMENT_ROOT'].$relative_path;
if(!file_exists($absolute_path)){
//检查是否有该文件夹,如果没有就创建,并给予最高权限
mkdir($absolute_path, 0700);
}
//文件名
$filename=$userid.".{$type}";
$new_file = $absolute_path.$filename;
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $img_content)))) {
return $relative_path.$filename;
}else{
return false;
}
}else{
return false;
}
}
/**
* 处理成圆图片,如果图片不是正方形就取最小边的圆半径,从左边开始剪切成圆形
* @param string $imgpath [description]
* @return [type] [description]
*/
public function radius_img($imgpath) {
$ext = pathinfo($imgpath);
$src_img = null;
switch ($ext['extension']) {
case 'jpg':
$src_img = imagecreatefromjpeg($imgpath);
break;
case 'jpeg':
$src_img = imagecreatefromjpeg($imgpath);
break;
case 'png':
$src_img = imagecreatefrompng($imgpath);
break;
}
$wh = getimagesize($imgpath);
$w = $wh[0];
$h = $wh[1];
$w = min($w, $h);
$h = $w;
$img = imagecreatetruecolor($w, $h);
//这一句一定要有
imagesavealpha($img, true);
//拾取一个完全透明的颜色,最后一个参数127为全透明
$bg = imagecolorallocate($img, 255, 255, 255);
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($src_img, $x, $y);
if (((($x - $r) * ($x - $r) + ($y - $r) * ($y - $r)) < ($r * $r))) {
imagesetpixel($img, $x, $y, $rgbColor);
}
}
}
return $img;
}
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Redis;
use DB;
use Log;
use App\Http\Controllers\Admin\Common;
class WxMiniProgramController extends Controller
{
/**
* [getzhongqiuqrCode 生成加油小程序二维码]中秋
* @param Request $req [description]
* @return [type] [description]
*/
public function getzhongqiuqrCode($page,$scene,$siteId=''){
// 加油小程序appid
$appid=config('wechat.app_id');
$secret=config('wechat.secret');
$imgcode=$this->createMiniCodes($appid,$secret,$page,$scene,$siteId);
// log::info($imgcode);
return $imgcode;
}
//生成加油微信小程序二维码,用户扫码登录小程序
public function createMiniCodes($appid, $secret, $page,$scene,$siteId){
$token=$this->getAccessToken($appid,$secret);
$url="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$token;
$content='{"scene":"'.$scene.'","page":"'.$page.'"}';
// 31_XPkKfdw8JcOv-Y2sPze1eL5cbRYZajWWaL5PfdCySprCJX1CLehtb0oVt9IZFEKksMKAPG4f4FPqn3sIJC85d0O5Xvg00tAx7oD_2zKTTV3d3ebbW_GKsXC2xETPeLgT1hFxH2iWZvbUMFWSZKNeAJANYB
$headerArray =array("Content-type:application/json;","Accept:application/json");
$ch = curl_init();
if (substr($url, 0, 5) == 'https') {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headerArray);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
$response = curl_exec($ch); //返回数据
if ($error = curl_error($ch)) {
die($error);
}
curl_close($ch);
return "data:image/jpeg;base64," . base64_encode($response);
}
/**
* [getJiayouqrCode 生成加油小程序二维码]
* @param Request $req [description]
* @return [type] [description]
*/
public function getJiayouqrCode(Request $req){
$siteId = $req->siteId;
// 加油小程序appid
$appid=config('wechat.app_id');
$secret=config('wechat.secret');
$imgcode=$this->createMiniCode($appid,$secret,$siteId);
// log::info($imgcode);
return response()->json(['result'=>1,'img'=>$imgcode]);
}
//生成加油微信小程序二维码,用户扫码登录小程序
public function createMiniCode($appid, $secret, $siteId){
$token=$this->getAccessToken($appid,$secret);
$url="https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=".$token;
$content='{"scene":"/pages/oil/index&id='.$siteId.'","page":"pages/interim/interim"}';
// 31_XPkKfdw8JcOv-Y2sPze1eL5cbRYZajWWaL5PfdCySprCJX1CLehtb0oVt9IZFEKksMKAPG4f4FPqn3sIJC85d0O5Xvg00tAx7oD_2zKTTV3d3ebbW_GKsXC2xETPeLgT1hFxH2iWZvbUMFWSZKNeAJANYB
$headerArray =array("Content-type:application/json;","Accept:application/json");
$ch = curl_init();
if (substr($url, 0, 5) == 'https') {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER,$headerArray);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
$response = curl_exec($ch); //返回数据
if ($error = curl_error($ch)) {
die($error);
}
curl_close($ch);
return "data:image/jpeg;base64," . base64_encode($response);
}
//生成加油微信小程序token
public function getAccessToken($appid,$secret){
$url = 'https://api.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$secret;//请求地址
$ch = curl_init();
if(substr($url,0,5)=='https'){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是否存在
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, $url);
$response = curl_exec($ch);
if($error=curl_error($ch)){
die($error);
}
curl_close($ch);
$json=json_decode($response,true);
return $json['access_token'];
}
}