前段时间公司做活动,有个合成图片的需求。 当时就想到用canvas,结果没想到一路走来全是坎儿! 今天有时间也就做个回顾,记录一下遇到的那些坑!
1、图片合成后,canvas的toDataURL获取的base64没有图片背景
这个问题当时在网上找了好久,发现图片会再存在跨域问题,或者没有在onload加载完图片后在画。
oImg.crossOrigin = "Anonymous"; 这句代码貌似可以解决部分跨域问题,但是我这里的情况略有不同,最后还是用了本地图片!
2、合成多张图片,后合成的总被覆盖,看不到
ps:gd是获取的绘图上下午变量。
下面这两个可以用来调整,类似 z-index 的感觉。
gd.globalCompositeOperation="source-over";
gd.globalCompositeOperation="source-over";
3、合成多张图片,或者第二张图片偶尔会合成失败
这个问题目前没有好的解决办法,之前用过两个onload,失败、然后事件连等、第二张不会合成失败了,但是获取的toDataURL又出了问题,base64无效。后来只有把需求砍掉了,有时间研究出来在写了!
4、对、想起一个头疼的问题,合成的图片清晰度不够,以后找到解决办法在补上吧!
还有一些坑暂时也想不起来了! 记性太差,以后遇到的坑,还是及时记下来的好,不然简直是隔夜忘......
下面就上代码!
var params = function (u, paras) {
var url = u;
var paraString = url.substring(url.indexOf("?") + 1, url.length).split("&");
var paraObj = {};
for (i = 0; j = paraString[i]; i++) {
paraObj[j.substring(0, j.indexOf("=")).toLowerCase()] = j.substring(j.indexOf("=") + 1, j.length);
}
var ret = paraObj[paras.toLowerCase()];
if (typeof(ret) == "undefined") {
return "";
} else {
return ret;
}
};
var imgUrl = decodeURI(params(location.search, "img"));
if(imgUrl){
$("#IMG").attr("src",imgUrl);
$("#weixinFenx").show();
$("#makeMy").on("click",function(){
$("#weixinFenx").hide();
/*setTimeout(function(){
$("#weixinFenx").remove();
},1000);*/
});
}
var W=document.documentElement.clientWidth;
var H=document.documentElement.clientHeight;
var mb=1;
var imgData='';
var select=[
'职场之路,与你相伴,真好!节日快乐~'
];
// swper轮播图
var ld=document.querySelector('#ld').src;
var galleryTop = new Swiper('.gallery-top', {
spaceBetween: 10,
loop:true,
// autoplay:2000,
// autoplayDisableOnInteraction:false,
loopedSlides: 5, //looped slides should be the same
onSlideChangeEnd: function(swiper){
var aImg=document.querySelectorAll('.gallery-top .swiper-wrapper img');
for(var i=0; i 640) {
W = 640;
}
var size = W / baseWidth;
function ptr(val){
return (val/100)*size;
}
var oCanvas = document.createElement('canvas');
if(document.getElementById('c1')==null){
// var oCanvas = $("");
// console.log(W,H)
oCanvas.id='c1';
// console.log(document.documentElement.style.fontSize,size);
// console.log((643/100)*size);
oCanvas.width=ptr(643);
oCanvas.height=ptr(829);
oBox.appendChild(oCanvas);
}
var w=(643/100)*size;
var h=(829/100)*size;
// console.log(w,h)
var oC = document.querySelector('#c1'); // E:\whs\weixin\member_branch_teacher_20170904\app\webroot\dream\js\make.js
var gd = oC.getContext('2d');
var oImg = new Image();
// oImg.crossOrigin="anonymous";
oImg.crossOrigin = "Anonymous";
// oImg.src = `dream/images/m-${mb}.png`;
oImg.src = mb;
var oImg2 = new Image();
// oImg.crossOrigin="anonymous";
oImg2.crossOrigin = "Anonymous";
// oImg2.src = 'dream/images/ld.png';
oImg2.src = ld;
function writeTextOnCanvas(ctx_2d, lineheight, bytelength, text ,startleft, starttop){
function getTrueLength(str){//获取字符串的真实长度(字节长度)
var len = str.length, truelen = 0;
for(var x = 0; x < len; x++){
if(str.charCodeAt(x) > 128){
truelen += 2;
}else{
truelen += 1;
}
}
return truelen;
}
function cutString(str, leng){//按字节长度截取字符串,返回substr截取位置
var len = str.length, tlen = len, nlen = 0;
for(var x = 0; x < len; x++){
if(str.charCodeAt(x) > 128){
if(nlen + 2 < leng){
nlen += 2;
}else{
tlen = x;
break;
}
}else{
if(nlen + 1 < leng){
nlen += 1;
}else{
tlen = x;
break;
}
}
}
return tlen;
}
for(var i = 1; getTrueLength(text) > 0; i++){
var tl = cutString(text, bytelength);
ctx_2d.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), startleft, (i-1) * lineheight + starttop);
text = text.substr(tl);
}
}
gd.font = ptr(30)+"px 微软雅黑";
gd.textAlign = 'left';
gd.textBaseline = 'middle';
var str = 'To:'+$('.to').val();
gd.fillText(str,ptr(20),ptr(506));
gd.font = ptr(30)+"px 微软雅黑";
gd.textAlign = 'right';
gd.textBaseline = 'middle';
var str = 'From:'+$('.form').val();
gd.fillText(str,ptr(620),ptr(750));
gd.font = ptr(26)+"px 微软雅黑";
gd.textAlign = 'center';
gd.textBaseline = 'middle';
var str = ' 这是我的明ptr(310),ptr(506)我的明信片';
var count=$('.val').val()?$('.val').val():select[$('.select').val()-1];
str=' '+count;
writeTextOnCanvas(gd,ptr(60),48,str,ptr(320),ptr(566));
oImg.onload= function(){
gd.globalCompositeOperation="destination-over";//source-over
gd.drawImage(
oImg,
0,0,643,829,
0,0,w,h
);
function convertBase64UrlToBlob(urlData,type){
var bytes=window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte
//处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length);
var ia = new Uint8Array(ab);
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i);
}
return new Blob( [ab] , {type : 'image/'+type});
}
var ctx = document.getElementById('c1');
var dataURL = ctx.toDataURL("image/png",1.0);/*data:image/png;base64,*/
var file1=convertBase64UrlToBlob(dataURL,"png");
$.ajax({
url:'',
type: "post",
contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
dataType: 'dataType',
timeout: 80000,
data: {
"img":dataURL.substring(22)
},
success: function(data) {
var res=JSON.parse(data);
console.log(JSON.parse(data));
ctx.style.display='none';
var fenImg=document.querySelector('.imgFen img');
var Img = document.createElement('img');
Img.id='imgURI';
Img.setAttribute('src', res.data);
fenImg.setAttribute('src', res.data);
oBox.appendChild(Img);
$("#imgURI").attr("width","75%");
$("#imgURI").attr("display","block");
$("#imgURI").attr("margin","0 auto");
},
error: function(data) {
console.log(data)
}
})
};
}
附上一张合成图!