在项目中,需要生成海报。有动态信息(微信头像、微信昵称、上传图片(oss链接)、二维码)+ 海报背景图生成一张海报。
技术支持:canvas 生成。
问题:canvas 图片跨域。
解决过程(填坑历程):
1.从网上存在如图解决办法 img.crossOrigin = "" (专业采坑,数年)。亲测无效。很是不解。
2.网上也存在后端服务解决
A.设置header头,或者nginx 服务配置等 允许访问
但是,存在问题(图片大部分为了优化,都会存放在第三方cdn.上面。这是第三方的配置,是否允许,自己很难控制)
0个小时。。。。。。。
1个小时.。。。。。。。。。。
0下午。。。。。。。。。。。。
1下午。。。。。。。。。。。。。
0天。。。。。。。。。。。。。。。。
解决办法:采用所有图片路径,转化为base64流,来处理。相对于本地图片了。此时,就避开了跨域问题。
图片路径,转base64,后端处理,更方便。
eg: php
/** * @param $url * @return bool|string * Name: master_imgUrl_base64 * User: wangjiapeng * Date: 2018/04/12 * Explain:CDN远程图片URL下载,并转化为base64 */ protected function master_imgUrl_base64($url){ if($url){ $header = array( '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); $data = curl_exec($curl); $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); if ($code == 200) {//把URL格式的图片转成base64_encode格式的! $imgBase64Code = "data:image/jpeg;base64," . base64_encode($data); return $imgBase64Code; }else{ return false; } }else{ return false; } }
附加,海报中需要生成二维码。
技术支持:jquery.qrcode.min.js
方法:1.html 中放入盒子
<!--二维码--> <div style="display: none;" id="qrcode">2. js
$("#qrcode").qrcode({ render: "canvas", text: data.info.u_url (要生成的url:例 https://blog.csdn.net/qq_37837134) }); var codeCanvas=document.getElementById("qrcode").getElementsByTagName("canvas")[0]; var codeContext = codeCanvas.getContext("2d"); var imgsSrc1 = codeCanvas.toDataURL('image/jpg'); do_canvasa(data.info,imgsSrc1); // 此方法 为canvas 生成海报 参数一:微信头像、微信昵称等 参数二:二维码
3.
function do_canvasa(data,imgsSrc1) {
//获取canvas var canvas = document.getElementById('canvas'); //设置宽高 //想获取高清图请*2,一般的直接等于Width就行 var Height = window.innerHeight*2; var Width = window.innerWidth*2; //canvas绘制需要的对象 var ctx = canvas.getContext("2d"); canvas.width = Width; canvas.height = Height; //获取图片 var mainImg = document.getElementById('mainImg'); //获取图片 var imgs = { bg: data.img_posters, //大背景 via: data.wx_img, //头像 pho:data.upload_img, //照片 qrCode: imgsSrc1, //二维码 }; var draw = {}; //载入图片 draw.into = function(){ var imgNum = 0; for(var key in imgs){ var img = new Image(); img.crossOrigin = ""; img.src = imgs[key]; imgs[key] = img; imgs[key].onload = function(){ imgNum++; if(imgNum == Object.keys(imgs).length) draw.drawImg(); } } } //绘制canvas draw.drawImg = function(){ //背景图 ctx.drawImage(imgs.bg, 0, 0, Width, Height); //头像 ctx.save(); ctx.arc(Width*0.14, Height*0.12, Width*0.075, 0, 360); ctx.clip(); ctx.drawImage(imgs.via, Width*0.065, Height*0.07, Width*0.16, calcHeight(imgs.via, Width*0.16)); ctx.restore(); //昵称5 //颜色 ctx.fillStyle = '#fff'; //字体设置 三个参数,font-weight font-size font-family ctx.font = '26px microsoft yahei'; //说明 // (scaled-0.62) ctx.fillText(''+data.wx_name+'', Width*0.225, Height*0.105); ctx.font = '24px microsoft yahei'; ctx.fillStyle = 'red'; ctx.textAlign="center"; ctx.fillText(''+data.order_num+'', Width*0.34, Height*0.134); //照片 ctx.save(); ctx.strokeStyle = '#fff'; ctx.lineWidth = 20; ctx.lineJoin = "round"; if(imgs.pho.height > imgs.pho.width) { ctx.strokeRect((Width-Height*0.3 / imgs.pho.height * imgs.pho.width)/2, (Height-Height*0.3)/2 + 80, Height*0.3 / imgs.pho.height * imgs.pho.width, Height*0.3 ); ctx.fillRect((Width-Height*0.3 / imgs.pho.height * imgs.pho.width)/2, (Height-Height*0.3)/2 + 80, Height*0.3 / imgs.pho.height * imgs.pho.width, Height*0.3 ); ctx.drawImage(imgs.pho, (Width-Height*0.3 / imgs.pho.height * imgs.pho.width)/2, (Height-Height*0.3)/2 + 80, Height*0.3 / imgs.pho.height * imgs.pho.width, Height*0.3); } else if(imgs.pho.height < imgs.pho.width){ ctx.strokeRect((Width-Width*0.7)/2, (Height - Width*0.7 / imgs.pho.width * imgs.pho.height) / 2 + 80, Width*0.7, Width*0.7 / imgs.pho.width * imgs.pho.height); ctx.fillRect((Width-Width*0.7)/2, (Height - Width*0.7 / imgs.pho.width * imgs.pho.height) / 2 + 80, Width*0.7, Width*0.7 / imgs.pho.width * imgs.pho.height); ctx.drawImage(imgs.pho, (Width-Width*0.7)/2,(Height - Width*0.7 / imgs.pho.width * imgs.pho.height) / 2 + 80, Width*0.7, Width*0.7 / imgs.pho.width * imgs.pho.height); } else { ctx.strokeRect((Width-440)/2, (Height-Width*0.7)/2 + 120, 440, 440); ctx.fillRect((Width-440)/2, (Height-Width*0.7)/2 + 120, 440, 440); ctx.drawImage(imgs.pho, (Width-440)/2, (Height-Width*0.7)/2 + 120, 440, 440); } ctx.restore(); //二维码 ctx.drawImage(imgs.qrCode, (Width-Width*0.22)/2 , Height*0.76, Width*0.22, calcHeight(imgs.qrCode, Width*0.22)); //获取base64格式的src var imgSrc = canvas.toDataURL('image/jpg'); mainImg.src = imgSrc; } draw.into(); function calcHeight(obj, w){ return w / obj.width * obj.height; } }
我为人人,人人为我;美美与共,天下大同;