canvas 实现图片预览和下载

最近接了个需要:要求点击一个按钮(预览分享图)生成一个图片实现预览,图片要求在服务器图片的基础上加上二维码和文字;点击保存相册按钮实现保存,具体需求如下;

思路:

1、先用qrcode生产二维码,获取二维码url(其实是图片的base64);

2、获取背景图,将背景图缩小绘制到画布上,

3、将二维码绘制到背景图上的指定地方,

4、绘制文字

5、最后获取画布的图片的base64,

6、调用a标签的downLoad属性下载图片;

 

以下是部分html代码:

 <div class="hideThis" id="closeBox" @click="exitPreview">
            <div class="st" @click="cancleBubble1($event)">
                <div class="frontClass">  <--用于预览的图片-->
                    <canvas id="canvasFront"></canvas>
                </div>
                <div class="sc-cover1-t1 hideThis"> <canvas id="canvasFrontDown" class="hideThis"></canvas></div>  <--因为画布的图片经过压缩不满足后期打印,这个div保存的是用于存放原图和二维码用于下载的图片-->
          </div>
            <div id="erweimaImg" class="hideThis"></div>  <--生成二维码临时存放-->
            <div class="sc-cover1-b" @click="cancleBubble2($event)">保存到相册</div>
</div>

以上是html,主要用到点击exitPreview函数移除隐藏,弹出窗口,并且在<canvas id="canvasFront"></canvas>进行绘制图片;

<div id="erweimaImg" class="hideThis"></div>用于临时存放二维码;

 

下面是部分js 代码:内含有比较清楚的介绍每个步骤 

  previewShare: function () {
                $("#previewBox").removeClass("hideThis");
                $("#closeBox").removeClass("hideThis");
                var url = vm.createQrcode();
                vm.sourceImg("图片上要写的文字", url);
            },
createQrcode: function () {
                $("#erweimaImg").qrcode({   //选择存放链接容器
                    width: 100, //width height如果不写默认是 256 256
                    height: 100,
                    text: "https://blog.csdn.net/weixin_41679874?orderby=ViewCount" //二维码的链接
                });

                //定义方法
                function canvasToImage(canvas) {
                    var image = new Image();
                    // 指定格式 PNG 图片后缀可自定义
                    image.src = canvas.toDataURL("image/png");
                    return image;
                }

                //找到需要转换的canvas
                var mycanvas1 = $('canvas')[$('canvas').length - 1];

                //进行方法转换
                var img = canvasToImage(mycanvas1);
                return img.src;
            },
sourceImg: function (text, url) {
                var canvas = document.getElementById("canvasFront");  // 获取指定画布
                var ctx = canvas.getContext("2d");  // 获取context 对象:
                var winWidth = window.innerWidth;  //获取设备宽度 当初测试以屏幕宽度为准 375
                var win = 207;   //closeBox 这个div的宽度                 
                var hei = 590.5; //closeBox 这个div的宽度
                var left = 146;   // 文字旋转的中心坐标
                var top = 470;   // 文字旋转的中心坐标
                if (winWidth <= 1024) {
                    var win1 = 207 * (winWidth / 375); 
                    var hei1 = 590.5 * (winWidth / 375);
                    var left1 = 146 * (winWidth / 375);
                    var top1 = 470 * (winWidth / 375);
                    var win2 = 118 * (winWidth / 375);
                    var left2 = 26 * (winWidth / 375);
                    var top2 = 42 * (winWidth / 375);
                    var size2 = 65 * (winWidth / 375);
                } else {
                    var win1 = 565;
                    var hei1 = 1613;
                    var left1 = 395;
                    var top1 = 1283;
                    var win2 = 322;
                    var left2 = 71;
                    var top2 = 114.6;
                    var size2 = 177;
                }// 以上的数字就是为了让div能适应不同屏幕的大小能让画布自适应大小
                canvas.setAttribute('width', win1 + 'px'); //设置画布宽
                canvas.setAttribute('height', hei1 + 'px'); // 设置画布高度   不设置会有默认
            
                var imgs = new Image();  // 创建两个图片对象
                var imgs2 = new Image();
                imgs.src = vm.frontImageId;  // 背景图的路径
                imgs2.src = url;              // 二维码的路径
                imgs.onload = function(){
                   ctx.drawImage(imgs, 0, 0, win1, hei1);
                };//图片加载完成再执行
                imgs2.onload =function () {
                    ctx.drawImage(imgs2, left2, top2, win2, win2);
                };//图片加载完成再执行

                

                var moveToRight = function () {
                  //  ctx.drawImage(imgs, 0, 0, win1, hei1);
                  //  ctx.drawImage(imgs2, left2, top2, win2, win2);
                    ctx.font = size2 + "px PingFangSC-Medium";// 画文字,文字的大小,不建议用rem,苹果不兼容,用px
                    ctx.fillStyle = "#ed6a1a"; //字体颜色
                    ctx.fontWeight = "bold";   //粗细
                    ctx.save();                // 将以上画好的内容定妆保存
                    ctx.translate(left1, top1);  // 设置旋转中心
                    ctx.rotate(Math.PI / 2 * 3);  // 设置旋转角度
                    ctx.fillText(text, 0, 0);   // 将文字绘制好并且完成保存之后的操作
                    ctx.restore();              // 把定妆保存的图片恢复融合旋转后的文字
                }
                setInterval(moveToRight, 0);

                // 如果对图片的清晰度和大小没有要求下面的可以不用看,下面只是将上面的参数变为原图大小
                var realcanvas = document.getElementById("canvasFrontDown");
                var realctx = realcanvas.getContext("2d");
                var realwin1 = 828;
                var realhei1 = 2363;
                var realleft1 = 590;
                var realtop1 = 1880;
                var realwin2 = 472;
                var realleft2 = 104;
                var realtop2 = 168;
                realcanvas.setAttribute('width', realwin1 + 'px'); // 画布匹配原图尺寸
                realcanvas.setAttribute('height', realhei1 + 'px');
                var realimgs = new Image();
                var realimgs2 = new Image();
                realimgs.src = vm.frontImageId;
                realimgs.setAttribute("crossOrigin", 'Anonymous'); //运行图片跨域,前提是你拿的背景图的服务器是允许跨域;
                realimgs2.src = url;
                realimgs.onload = drawImg;//图片加载完成再执行
                realimgs2.onload = drawImg;//图片加载完成再执行
                function drawImg() {
                    realctx.drawImage(realimgs, 0, 0, realwin1, realhei1);
                    realctx.drawImage(realimgs2, realleft2, realtop2, realwin2, realwin2);
                    realctx.font = "240px PingFangSC-Medium";
                    realctx.fillStyle = "#ed6a1a";
                    realctx.fontWeight = "bold";
                    realctx.save();
                    realctx.translate(realleft1, realtop1);
                    realctx.rotate(Math.PI / 2 * 3);
                    realctx.fillText(denomination, 0, 0);
                    realctx.restore();
                }
            },

图片生成之后,记得将隐藏属性关掉,才能展示图片

我项目成图为:

左边是效果图,右边是原图 下面的是预览图;

 

接下来是保存的js:

点击保存按钮会执行以下js

cancleBubble2:function (event) {
                event.stopPropagation();  //方法阻止事件冒泡到父元素,阻止任何父事件处理程序被执行。父级点击灰色区域会关掉预览,保存相册要忽略父级的点击事件
                var   frontBase = document.getElementById("canvasFront").toDataURL("image/png"); // 保存预览图
           //   var frontBase1 = document.getElementById("canvasFrontDown").toDataURL("image/png");  //保存原比例图,隐藏的那张真实图片
                try {
                    //调用IOSjs 
                    window.webkit.messageHandlers.XXXX.postMessage();
                } catch (e) {
                    try {
                        //调用Android  js;
                        window.fnxls.XXXX(imgSrc);//,
                    } catch (e) {
                        //保存图片方法
                        vm.saveImg("couponFrontImg", frontBase);
                    }
                }
            },

/**
 * @param fileName 下载的图片名称,默认:fnImg+时间戳
 * @param content URL 或者图片内容(base64内容)
 */
saveImg:function (fileName,content) {
    if(content.indexOf('data:image')>-1){
        // base64 图片操作
        vm.saveImgByBase64(fileName,content);
    }else{
        //path 图片操作
      //  vm.saveImgByUrl(fileName,content); 这个方法网上很多就不贴出来了
    }
},

/**
 * @param fileName 保存图片的名字,默认:fnImg+时间戳
 * @param base 图片内容
 */
saveImgByBase64:function (fileName, base) {
    if (!fileName || !/\S/.test(fileName)) {
        fileName="fnImg"+new Date().getMilliseconds();
    }
    var aLink = document.createElement('a');  // 创建a标签
    var blob = vm.base64ToBlob(base); //获得一个blob二进制大对象,

    var evt = document.createEvent("HTMLEvents"); // 获取base64中的图片格式
    evt.initEvent("click", true, true);//initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为  
    aLink.download = fileName;
    aLink.href = Windows.URL.createObjectURL(blob); // window.webkitURL和window.URL是一样的,担心不兼容的可以加多个if判读
    aLink.dispatchEvent(new MouseEvent('click', {bubbles: true, cancelable: true, view: window}));//兼容火狐;
};


//base64转blob  这个方法网上也很多,但是基本一样自己可以网上看看
base64ToBlob:function (code) {
    var parts = code.split(';base64,');
    var contentType = parts[0].split(':')[1];
    var raw = window.atob(parts[1]);
    var rawLength = raw.length;
    var uInt8Array = new Uint8Array(rawLength);
    for (var i = 0; i < rawLength; ++i) {
        uInt8Array[i] = raw.charCodeAt(i);
    }
    return new Blob([uInt8Array], {type: contentType});
}

我这边因为是有移动端的,所以直接调用移动端的js,不知道在手机的浏览器是否可以执行,但是本人在谷歌浏览器和IE浏览器是没有问题;

 

有不清楚的可以留言,有时间会回复,有不同看法的欢迎发表;

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值