在项目中,需要生成海报。有动态信息(微信头像、微信昵称、上传图片(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: 奔跑吧笨笨
* 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
});
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) {
// 原图片
var oldImg = data.upload_img;
// 新图片
var newImg ='';
$('.close').on('click',function(){
$('.dialog').fadeOut();
$('#cutImg').fadeOut();
});
//获取裁剪图片
var clipArea =new PhotoClip("#clipArea", {
size: [237,263],//裁剪框大小
outputSize:[0,0],//打开图片大小,[0,0]表示原图大小
img:oldImg,// 原图片
ok:"#sure",
loadStart:function() {//图片开始加载的回调函数。this 指向当前 PhotoClip 的实例对象,并将正在加载的 file 对象作为参数传入。(如果是使用非 file 的方式加载图片,则该参数为图片的 url)
// $(".loading").removeClass("displaynone");
},
// $(".loading").addClass("displaynone");
},
//确定
done:function(dataURL) {//裁剪完成的回调函数。this 指向当前 PhotoClip 的实例对象,会将裁剪出的图像数据DataURL作为参数传入。
// console.log(dataURL);//dataURL裁剪后图片地址base64格式提交给后台处理
newImg = dataURL;
canvasImg();
$('#cutImg').fadeOut();
$('.dialog').fadeIn();
$(".pos").fadeIn();
}
});
//取消
$('.back').on('click',function(){
$('#cutImg').fadeOut();
});
function canvasImg(){
//获取canvas
var canvas =document.getElementById('canvas');
//设置宽高
//想获取高清图请*2,一般的直接等于Width就行
var Height =window.innerHeight*2;
var Width =window.innerWidth*2;
//canvas绘制需要的对象
// console.log(Width, canvas.width, $('.poster').width())
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:newImg,
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.09,Height*0.113,Width*0.065,0,360);
ctx.clip();
ctx.drawImage(imgs.via,Width*0.022,Height*0.072,Width*0.14,calcHeight(imgs.via,Width*0.14));
ctx.restore();
//颜色
ctx.fillStyle ='#fff';
//字体设置 三个参数,font-weight font-size font-family
ctx.font ='26px microsoft yahei';
//说明
// (scaled-0.62)
ctx.fillText(''+data.wx_name+'',Width*0.168,Height*0.11);
ctx.font ='bold 24px microsoft yahei';
ctx.fillStyle ='red';
ctx.textAlign="center";
ctx.fillText(''+data.order_num+'',Width*0.305,Height*0.14);
//照片
ctx.save();
//圆角矩形
CanvasRenderingContext2D.prototype.roundRect =function (x, y, w, h, r) {
//if (w < 2 * r) r = w / 2;
//if (h < 2 * r) r = h / 2;
this.beginPath();
this.moveTo(x+r, y);
this.arcTo(x+w, y, x+w, y+h, r);
this.arcTo(x+w, y+h, x, y+h, r);
this.arcTo(x, y+h, x, y, r);
this.arcTo(x, y, x+w, y, r);
// this.arcTo(x+r, y);
this.closePath();
return this;
};
ctx.roundRect((Width-237 *Width /374)/2 +7,Height *367 /976 +8,237 *Width /374 -15,258 *Height /664 -6,20);
ctx.fillStyle ='#fff';
ctx.fill();
ctx.clip();
ctx.drawImage(imgs.pho, (Width-237 *Width /374)/2 +7,Height *367 /976 +8,237 *Width /374 -15,258 *Height /664 -6);
ctx.restore();
//二维码
ctx.drawImage(imgs.qrCode,44 /374 *Width ,525 /662 *Height,85 *Width /374,calcHeight(imgs.qrCode,85 *Width /374));
//获取base64格式的src
var imgSrc =canvas.toDataURL('image/jpg');
mainImg.src =imgSrc;
};
draw.into();
function calcHeight(obj, w){
return w / obj.width * obj.height;
}
$('#mainImg').load(function() {
$(".pos").fadeOut()
});
}
}
我为人人,人人为我;美美与共,天下大同;
csdn链接:canvas 图片跨域