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

思路:

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 256height: 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;}//找到需要转换的canvasvar 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;  //获取设备宽度 当初测试以屏幕宽度为准 375var 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,苹果不兼容,用pxctx.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浏览器是没有问题;

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

canvas 实现图片预览和下载相关推荐

  1. element图片预览添加下载图片功能.

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.element自带的大图预览,没有提供下载功能的api,而实际使用中总是有一些需求需要用到这个功能,所以只有自己对 ...

  2. java图片预览上传_java实现文件上传、下载、图片预览

    这篇文章主要介绍了java实现文件上传.下载.图片预览,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 多文件保存到本地: @ResponseBody ...

  3. 微信开发php插件下载图片,微信开发之微信jsapi选择图片,上传图片,预览和下载图片方法...

    参数描述 appId公众号的唯一标识 应用id timestamp生成签名的时间戳 nonceStr生成签名的随机串 signature签名 上述表格中的四个参数是初始化调用微信jsapi的凭证,咱们 ...

  4. 小程序自定义图片预览和多图下载的实现

    小程序开发中图片列表的需求再常见不过了,通常都会配合大图预览和图片下载的功能 但是微信又没有提供可自定义的图片预览功能,有时候会有需求在预览大图的时候收藏或者下载啥的用 wx.previewImage ...

  5. Vue+wangeditor富文本+element——--上传+下载文件+图片预览

    一:上传文件 HTML <el-upload class="upload-demo" action="haircut/upload" :on-previe ...

  6. uniapp图片或文件的预览和下载,兼容ios+安卓+浏览器

    一.前言 在uniapp的APP日常开发中,我们时常遇到一些兼容性问题,正如本文所提到的图片的预览和下载.在此功能的开发中,我常遇到以下四个问题: 图片预览功能实现,但是PDF,word,xls文件无 ...

  7. 【实战】前端必会技巧 —— window.open 实现图片预览而非下载

    文章目录 一.问题 二.解决 三.其他尝试 四.拓展学习 1.window.open 语法 实例 2.document.write 语法 实例 一.问题 多个 图片 url (用逗号分隔开) 图片 u ...

  8. Java 实现图片或文件在线预览及下载

    效果图 图片 pdf 代码 @GetMapping("/downFile")public void downFile(HttpServletResponse response, H ...

  9. html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器

    原文:html5 图片上传,支持图片预览.压缩.及进度显示,兼容IE6+及标准浏览器 以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一 ...

最新文章

  1. linux watch 命令简介 监测 监控变化
  2. 初探linux子系统集之led子系统(一)【转】
  3. stm32 IAP在线升级的个人经验以及实现方法
  4. Angular2入门--架构概览
  5. 由于权限引起的Tomcat中项目某些页面访问不了
  6. 几个有用的word小技巧,保准提升效率~
  7. 计算机二级计划总结,计算机二级细节总结
  8. 第四届nBazaar技术交流会归来,收获颇丰
  9. ES6进阶Async与Await,你不知道的同步与异步
  10. tp5 查询求和_tp5 sum某个字段相加得到总数的例子
  11. WPS最大的败笔是“免费用,广告弹窗”,难怪用户纷纷使用office
  12. 从零开始实现 AlphaGo(一)
  13. 戴尔服务器安装win2008找不到硬盘
  14. matlab可见光通信,可见光通信研究工作matlab代码
  15. 关于丢番图方程x^2+y^2=n
  16. 国产开源项目管理软件ZenTao
  17. flutter图片聊天泡泡_Flutter极致的业务封装——各类聊天气泡(一)
  18. Java正则表达式简单入门
  19. ARM通用中断控制器GIC之中断处理状态机 Interrupt handling state machine
  20. word2vec你可能不知道的秘密

热门文章

  1. 大数据学习之Hive
  2. FPGA开发工具套餐搭配推荐及软件链接(工程师们转起来)
  3. 用javascript根据当前年月获得当前季度
  4. 这个世界上有三种几何学
  5. 用python对excel进行数据处理与分析操作
  6. 留学生论文essay写作字数不够怎么办?
  7. 被降级or地位凸显,技术研究院不同命运背后的企业技术底色
  8. Linux从入门到实战 ---- 磁盘分区
  9. Android获取手机屏幕像素大小
  10. VC用TTS实现文字语音朗读