canvas 图片的合成

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_30907803/article/details/82619999

需求情景:

二维码生成的图片底部  添加  该二维码的说明文字,再合并成一张新的图片。

参考链接:

图片合并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异步执行导致数据参数混乱

猜你喜欢

转载自blog.csdn.net/baidu_30907803/article/details/82619999