需求情景:
二维码生成的图片底部 添加 该二维码的说明文字,再合并成一张新的图片。
参考链接:
图片合并https://www.jianyu87.com/content/website/33.html
http://www.w3dev.cn/article/20150929/html-draw-to-image.aspx
https://www.jb51.net/html5/628961.html
文字居中https://blog.csdn.net/u013571833/article/details/52346422
采坑:https://blog.csdn.net/awe5566/article/details/18913679
技术方案:
1、二维码生成技术 qrcode
2、合并图片技术 canvas
上代码:
1、二维码生成,集成jquery.qrcode.min.js生成二维码。
由于二维码的生成有两个,一个是生成缩略图用来预览的,另一个则是生成300*300的大的二维码图,用于下载的。
//会议室列表=》下载会议室二维码=》创建
function createQrCode(type,size,roomUuid) {
var options = {
// render method: 'canvas', 'image' or 'div'
render: 'image',
minVersion: 6,
maxVersion: 40,
ecLevel: 'H',
size: size,
fill: '#000',
background: null,
text: 't=jump&f=oppo-it-hg&app_index_path=#/booking?roomid=' + roomUuid,
radius: 0.5,
quiet: 1,
mode: 2,
mSize: 0.1,
mPosX: 0.5,
mPosY: 0.5,
label: 'OMeet',
fontname: 'sans',
fontcolor: '#69cf47',
image: null
};
if(type == 'small'){
$('#'+roomUuid).empty().qrcode(options);
}else{
$('#qrcodeImg').html("");//移除已生成的避免重复生成
$('#qrcodeImg').empty().qrcode(options);
}
}
2、把生成的300*300二维码图添加文字 再合并成一张图片
利用html5的canvas技术
//会议室列表=》下载会议室二维码
$scope.downCodeImg = function(room){
//生成二维码
createQrCode('big',300,room.uuid);
//给二维码图片添加底部文字,重新生成图片
$('#qrcodeImg img').attr("id","codeImg");
var codeImg = document.getElementById("codeImg");
$('#downLoadImg').html(" ");//清除之前图片的数据
var canvas = document.createElement("canvas");
canvas.setAttribute('id',"canvas" + room.uuid);
canvas.setAttribute('width',"300");
canvas.setAttribute('height',"350");
$('#downLoadImg').append(canvas);
var context = canvas.getContext("2d");
//由于图片是异步的,需要保证图片资源拿到后再渲染到canvas
preImage(codeImg.src,function(){
//canvas 添加二维码图片
context.drawImage(codeImg,0,0,300,300);
//canvas 底部添加二维码的名称
context.fillStyle="#69CF47 ";
context.font = "15px Verdana";
context.fillText(room.name,0,315);
//创建下载合并后的图片
var srcImg = new Image();
srcImg.src = canvas.toDataURL('images/png');
$('#downLoadImg').append(srcImg);
var a = document.createElement('a');
a.download = room.name;
a.href = $('#downLoadImg img').attr('src');
a.click();
});
};
注意:由于Chrome中canvas上drawImage无法画出image,则需要图片预加载方法
//由于图片是异步的,需要保证图片资源拿到后再渲染到canvas
function preImage(url,callback){
var img = new Image(); //创建一个Image对象,实现图片的预下载
img.src = url;
if (img.complete) { // 如果图片已经存在于浏览器缓存,直接调用回调函数
callback.call(img);
return; // 直接返回,不用再处理onload事件
}
img.onload = function () { //图片下载完毕时异步调用callback函数。
callback.call(img);//将回调函数的this替换为Image对象
};
}
3、批量下载二维码,使用for循环执行downCodeImg()方法,但是批量下载的图片的内容是一样的,这是因为js的异步执行代码的结果,因此使用setInterval把每次执行的downCodeImg()事件分隔开,实现下载到不同的二维码数据。
//会议室列表=》下载会议室二维码
$scope.downLoadAllQRcode = function(){
//获取所有会议室数据
$scope.getAllMeetingRoomData().then(function () {
$scope.count = 0;
$scope.downCodeImg($scope.meetingRoomAllList[0]);
$scope.timer = setInterval(function () {
if ($scope.count < $scope.meetingRoomAllList.length-1) {
$scope.count++;
$scope.downCodeImg($scope.meetingRoomAllList[$scope.count]);
} else {
clearInterval($scope.timer);
}
}, 2000)
}, function (data) {
console.log("请求会议室数据失败");
});
};
难点:图片异步预加载,js异步执行导致数据参数混乱