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 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 实现图片预览和下载相关推荐
- element图片预览添加下载图片功能.
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.element自带的大图预览,没有提供下载功能的api,而实际使用中总是有一些需求需要用到这个功能,所以只有自己对 ...
- java图片预览上传_java实现文件上传、下载、图片预览
这篇文章主要介绍了java实现文件上传.下载.图片预览,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 多文件保存到本地: @ResponseBody ...
- 微信开发php插件下载图片,微信开发之微信jsapi选择图片,上传图片,预览和下载图片方法...
参数描述 appId公众号的唯一标识 应用id timestamp生成签名的时间戳 nonceStr生成签名的随机串 signature签名 上述表格中的四个参数是初始化调用微信jsapi的凭证,咱们 ...
- 小程序自定义图片预览和多图下载的实现
小程序开发中图片列表的需求再常见不过了,通常都会配合大图预览和图片下载的功能 但是微信又没有提供可自定义的图片预览功能,有时候会有需求在预览大图的时候收藏或者下载啥的用 wx.previewImage ...
- Vue+wangeditor富文本+element——--上传+下载文件+图片预览
一:上传文件 HTML <el-upload class="upload-demo" action="haircut/upload" :on-previe ...
- uniapp图片或文件的预览和下载,兼容ios+安卓+浏览器
一.前言 在uniapp的APP日常开发中,我们时常遇到一些兼容性问题,正如本文所提到的图片的预览和下载.在此功能的开发中,我常遇到以下四个问题: 图片预览功能实现,但是PDF,word,xls文件无 ...
- 【实战】前端必会技巧 —— window.open 实现图片预览而非下载
文章目录 一.问题 二.解决 三.其他尝试 四.拓展学习 1.window.open 语法 实例 2.document.write 语法 实例 一.问题 多个 图片 url (用逗号分隔开) 图片 u ...
- Java 实现图片或文件在线预览及下载
效果图 图片 pdf 代码 @GetMapping("/downFile")public void downFile(HttpServletResponse response, H ...
- html5 图片上传,支持图片预览、压缩、及进度显示,兼容IE6+及标准浏览器
原文:html5 图片上传,支持图片预览.压缩.及进度显示,兼容IE6+及标准浏览器 以前写过上传组件,见 打造 html5 文件上传组件,实现进度显示及拖拽上传,兼容IE6+及其它标准浏览器,对付一 ...
最新文章
- linux watch 命令简介 监测 监控变化
- 初探linux子系统集之led子系统(一)【转】
- stm32 IAP在线升级的个人经验以及实现方法
- Angular2入门--架构概览
- 由于权限引起的Tomcat中项目某些页面访问不了
- 几个有用的word小技巧,保准提升效率~
- 计算机二级计划总结,计算机二级细节总结
- 第四届nBazaar技术交流会归来,收获颇丰
- ES6进阶Async与Await,你不知道的同步与异步
- tp5 查询求和_tp5 sum某个字段相加得到总数的例子
- WPS最大的败笔是“免费用,广告弹窗”,难怪用户纷纷使用office
- 从零开始实现 AlphaGo(一)
- 戴尔服务器安装win2008找不到硬盘
- matlab可见光通信,可见光通信研究工作matlab代码
- 关于丢番图方程x^2+y^2=n
- 国产开源项目管理软件ZenTao
- flutter图片聊天泡泡_Flutter极致的业务封装——各类聊天气泡(一)
- Java正则表达式简单入门
- ARM通用中断控制器GIC之中断处理状态机 Interrupt handling state machine
- word2vec你可能不知道的秘密