关于html2canvas:JS下载图片的方法总结

有没有小伙伴在开发“纯前端下载图片”性能时,遇到以下的场景?1. 下载已存在的图片2. 下载某个元素的内容分享解决以上问题的办法下载已存在的图片:应用canvas画图,a标签下载export function downloadImg(imgUrl: string, imgTitle: string) { var img = new Image(); img.src = imgUrl; // 必须设置,否则canvas中的内容无奈转换为blob img.setAttribute('crossOrigin', 'Anonymous'); img.onload = function () { var canvas = document.createElement('canvas'); canvas.width = img.width; canvas.height = img.height; let ctx: any = canvas.getContext('2d'); // 将img中的内容画到画布上 ctx.drawImage(img, 0, 0, canvas.width, canvas.height); // 将画布内容转换为Blob canvas.toBlob(blob => { // blob转为同源url var blobUrl = window.URL.createObjectURL(blob); // 创立a链接 var a = document.createElement('a'); a.href = blobUrl; a.download = imgTitle || '下载图片'; // 设置图片名称 // 触发a链接点击事件,浏览器开始下载文件 a.click(); }); };}下载某个元素的内容:应用html2canvas插件进行截图,a标签下载官网:http://html2canvas.hertzen.com/ ...

October 19, 2022 · 1 min · jiezi

关于html2canvas:html2canvas将指定区域导出为图片js将div导出为图片

如何应用JS截取HTML页面为图片呢,html2canvas.js这个插件能够轻松实现。这个原理很简略,就是html2canvas.js能够将当页面渲染成一个Canvas图片,而后保留下来即可。它不须要来自服务器任何渲染,整张图片都是在客户端浏览器创立。 代码<!DOCTYPE html><html><head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://cdn.staticfile.org/twitter-bootstrap/4.3.1/css/bootstrap.min.css"> <title>将指定区域导出图片</title> <script type="text/javascript" src="https://cdn.staticfile.org/html2canvas/0.4.0/html2canvas.js"></script></head><script type="text/javascript">// 导出图片function CreatImg() { console.log('test'); html2canvas(document.getElementById('view'), { onrendered: function(canvas) { // 创立一个canvas // document.body.appendChild(canvas); dataUrl=canvas.toDataURL("image/jpeg", 1.0); DownLoadImg(dataUrl.replace("data:image/jpeg;base64,", "")) }, });}function DownLoadImg(content){ // 格局 var imageType='png'; // 文件名 var fileName=Date.now(); var raw = window.atob(content); var rawLength = raw.length; var uInt8Array = new Uint8Array(rawLength); for(var i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } var blob = new Blob([uInt8Array], {type:'image/'+imageType}); var aLink = document.createElement('a'); var evt = document.createEvent("HTMLEvents"); evt.initEvent("click", true, true); aLink.download = fileName; aLink.href = URL.createObjectURL(blob); aLink.click();}</script><body> <div id="view" style="background:#f2f2f2 100%; width: 600px;margin:50px auto;"> <p style="text-align: center;padding:15px 0 20px;font-size:17px;font-weight:bold;height: 0;">2022年高考意愿热门业余</p> <table class="table"> <thead> <tr> <th style="width: 60px;vertical-align:middle;text-align:center;">序号</th> <th style="width: 220px;vertical-align:middle;text-align:center;">业余</th> <th style="width: 120px;vertical-align:middle;text-align:center;">业余代码</th> <th style="width: 80px;vertical-align:middle;text-align:center;">学制 </th> <th style="width: 110px;vertical-align:middle;text-align:center;">授予学位</th> </tr> </thead> <tbody> <tr> <td style="vertical-align:middle;text-align:center;">1</td> <td style="vertical-align:middle;text-align:center;">临床医学</td> <td style="vertical-align:middle;text-align:center;">100201K</td> <td style="vertical-align:middle;text-align:center;">五年</td> <td style="vertical-align:middle;text-align:center;">医学学士</td> </tr> <tr> <td style="vertical-align:middle;text-align:center;">2</td> <td style="vertical-align:middle;text-align:center;">计算机科学与技术</td> <td style="vertical-align:middle;text-align:center;">080901</td> <td style="vertical-align:middle;text-align:center;">四年</td> <td style="vertical-align:middle;text-align:center;">工学学士</td> </tr> <tr> <td style="vertical-align:middle;text-align:center;">3</td> <td style="vertical-align:middle;text-align:center;">软件工程</td> <td style="vertical-align:middle;text-align:center;">080902</td> <td style="vertical-align:middle;text-align:center;">四年</td> <td style="vertical-align:middle;text-align:center;">工学学士</td> </tr> <tr> <td style="vertical-align:middle;text-align:center;">4</td> <td style="vertical-align:middle;text-align:center;">航空航天工程</td> <td style="vertical-align:middle;text-align:center;">082001</td> <td style="vertical-align:middle;text-align:center;">四年</td> <td style="vertical-align:middle;text-align:center;">工学学士</td> </tr> <tr> <td style="vertical-align:middle;text-align:center;">5</td> <td style="vertical-align:middle;text-align:center;">汉语言文学</td> <td style="vertical-align:middle;text-align:center;">050101</td> <td style="vertical-align:middle;text-align:center;">四年</td> <td style="vertical-align:middle;text-align:center;">文学学士</td> </tr> </tbody> </table> </div> <input type="button" value="导出图片" onclick="CreatImg()" style="width: 120px;height: 50px;margin:20px auto;display: block;"><br/></body></html>动图Demo ...

July 13, 2022 · 1 min · jiezi

关于html2canvas:前端生成海报

前端截图 前端生成海报 保留图片内容为div通过html2canvas截图 生成Bob | base64保留到本地(下载办法无奈下载,生成图片长按保留到本地)style * { margin: 0; padding: 0; list-style: none; } .view { width: 375px; height: 667px; position: relative; color: #FFFFFF; text-align: center; font-size: 20px; background: #409EFF; } .title { width: 100%; font-size: 30px; position: absolute; top: 50px; left: 50%; transform: translateX(-50%); } .content { width: 100%; font-size: 16px; position: absolute; top: 100px; left: 50%; transform: translateX(-50%); } .result { width: 375px; height: 667px; } .result>img { width: 100%; height: 100%; } .btn { padding: 10px; } button { padding: 6px 10px; }html ...

July 8, 2022 · 1 min · jiezi

关于html2canvas:javascript实现网页截图导出方案

前言网页截图导出不是一个十分高频的需要,但时不时的也会遇到。这里总结一下零碎的解决方案,而后从中抉择适合本人的。 截图导出能够看到是两个性能,第一步实现截图,第二步实现导出也就是下载能力。 截图实现首先,咱们必须明确失常javascript是运行在浏览器里的,自身没有截图的能力。所以要想实现截图,必须通过其余曲折计划实现,废话少说,间接上论断。 前端计划1 canvas代表库html2canvas也有中文文档 实现原理:html2canvas 是一个 HTML 渲染器,屏幕截图是基于 DOM,因而生成的图片并不一定 100% 统一,因为它没有制作理论的屏幕截图,而是依据页面上可用的信息构建屏幕截图。文档介绍的比较清楚,canvas只是去还原dom的展现成果。 依据实现原理,能够设想,实现老本还是比拟高的,须要解析dom和css款式,而且css款式不肯定能完满映射到canvas,另外还会受限于canvas收到的一些限度,比方跨域资源问题。 前端计划2 svg代表库dom-to-image 实现原理:外围因素是SVG 的一个个性,容许在 <foreignObject> 标签中蕴含任意的 HTML 内容。所以为了渲染该dom节点,须要如下步骤: 递归克隆原始DOM节点计算节点和每个子节点的款式并将其复制到相应的克隆,并且要从新创立伪元素,因为它们当然不会以任何形式克隆嵌入网页字体,链接所有css款式到style标签,利用到clone节点嵌入图像 在 <img> 元素中嵌入图像 URL 背景 CSS 属性中应用的内嵌图像,以相似于字体的形式将克隆的节点序列化为 XML将 XML 包裹到 <foreignObject> 标签中,而后包裹到 SVG 中,而后使其成为数据 URL创立一个以 SVG 作为源的 Image 元素,并将其出现在您也已创立的离屏画布上,而后从画布中读取内容嗯,这就是svg形式实现了,和canvas形式一样,须要咱们解决dom,css和资源,然而后续的绘制渲染工作交给了浏览器,所以加重了很多工作量和代码量。 服务端计划代表形式 puppeteer实现Puppeteer 是一个 Node 库,它提供了一个高级 API 来通过 DevTools 协定管制 Chromium 或 Chrome。这里具体就不介绍了,咱们只应用它的截图性能。 这个就是真正的截图能力了,官网有demo。 思考到业务层的页面都须要用户拜访权限,所以正确的步骤应该是: 启动一个node服务,利用puppeter实现截图能力客户端发动一个申请,携带cookie第一步启动的服务解决此申请,生成图片,地址返回给客户端客户端拿到图片资源,进行下载即可比照html2canvas长处简略页面截图成果还能够,兼容性还好 毛病局部款式无奈反对简单页面,惨不忍睹。cors能够解决跨域,然而理论利用还是问题百出实现非常复杂,难以改变在咱们我的项目简直无奈应用 dom-to-image长处实现简略,可下载后自行改变源码还原度良好,尤其chrome反对十分好毛病safari反对不是很好,不过一些问题能够解决根本能反对业务需要 后端截图长处实在截图,终极计划,无兼容问题毛病实现流程略微繁琐须要思考 用户权限认证问题导出实现导出也就是下载文件到本地 a标签原理是通过a标签的download属性实现下载。 // 根本应用<a href="/images/xxxxx.jpg" download="filename">// 脚本触发const download = (filename, url) => { let a = document.createElement('a'); a.style = 'display: none'; // 创立一个暗藏的a标签 a.download = filename; a.href = url; document.body.appendChild(a); a.click(); // 触发a标签的click事件 document.body.removeChild(a);}blob文件流对象这个须要服务端反对,发动申请,服务端返回数据流,而后前端触发下载。具体就不多说了,网上有很多文章。 ...

October 22, 2021 · 1 min · jiezi

Columns多栏布局妙用解决用jspdf加html2canvas生成PDF时文字或图片被分页无情截断问题

前言生成PDF有很多种方案,现在只讨论用jspdf加html2canvas生成多页PDF时,相信用过的人也遇到如果文字或图片卡在分页位置处被无情裁断的问题。再次之前先简单介绍下我们用于解决问题的属性。 Columns 属性介绍columns:100px 3; //每列多少宽度 分多少列 也就是:column-count:3 // 分多少列column-width: 100px //每列多少宽度 column-fill: auto; //列排序充列 //默认是balance 就是代表尽量平均的内容; auto会设置成填满 往后铺 column-gap:40px; //设置列之间的间隔column-rule:4px outset #ff6430; //列与列之间的分隔线 宽度 线类型 颜色 也就是:column-rule-width //列与列之间的分隔线 宽度column-rule-style //列与列之间的分隔线 类型column-rule-color //列与列之间的分隔线 颜色 column-count:3; //分成多少列column-fill: auto; //列排序充列 默认是balance 就是代表尽量平均的内容; auto会设置成填满 往后铺 column-gap:40px; //列与列之间的距离column-rule:4px outset #ff6430; // 列与列之间的分隔线在线写html 可以过去试试:https://www.runoob.com/try/tr... 浏览器的兼容兼容截止我编写时间2019.09.07 实际应用:好,现在重新回到我们的问题。这个问题是很正常的,事关我们是用画布截图然后放进去PDF里面,而画布只会根据高度够了就截一张,它是不会去监控那个问题是不是刚好卡在字体或图片的中间呢~ 例如: 我前阵子也遇到相同的问题,我这边的解决方法是,舍弃截图从上往下截的截图: 方案: 改用在排版时就已经分页排版好,除了封面外,其它时间页头页脚浮动是页面上方,截图是一页一页的截,这样好处是前端能清晰掌握整个过程和排版甚至是分页的计算。【采用】 那么如果能解决按每页的排呢??? 条件发射解决方法:循环页面元素,计算该元素是否刚好卡在一页的高度位置,如果是, 那么我们把它后面的就不显示了,或者插入个分页结束符等; 很明显这个是行不通的。 一方面是:因为整个document下来 元素很多 大量循环所有的元素来监控也很不科学; 另一方面:现在这种基于dom结构渲染完了 ,生插一个标签的结束符。例如</div>这种,也是算不清有多少个种类不同的结束符; 所以这很明显是个错误示范 我们停止对于这边的思考。 ...

September 7, 2019 · 1 min · jiezi

生成海报前端-python

我最近没有摸鱼,一直都在工作。只不过目前需要爬一点数据 python 做的,之后看机会分享一下。 忙着忙着老大说要生成海报,有个活动要给每个用户来个分享图。 想法PS 批处理?脚本? 能甩出去的活都甩出去,机智如我啊python 处理图像(PIL)。这么坑的想法,当然不是我想的了。虽然我实现了写个页面调用之前生成长截图的服务。之前有个为了方便分享微信,做了生成长截图的服务。写个新的页面用一下即可。我堂堂前端er,怎么能一直用别的工具呢?我的锤子呢?ps处理这个方案,经过我调研行不通。(也有可能是我菜)对于批量打码,统一操作这类的还可以。对于需要对应名字之类的比较无力 python老大说 python。py 使用 PIL 库 写起来还蛮简单的。py 使用这段时间以来就是感觉这个编码格式极其难受。有没有大佬解救我一下。 根据不同的类型输出数据txt 使用字体,输出到对应位置image 图片,覆盖输出到对应位置。mask=img要注意针对 png 来使用qrcode 生成对应二维码通过上面的类型,来增加我们代码的扩展性。 代码# -*- coding: utf-8 -*-from PIL import Image, ImageDraw, ImageFontimport qrcodeimport time;import redef AddMoney(data): bg = Image.new('RGBA', (data['width'], data['height'])) for item in data['list']: print(item) if item['type'] == 'qrcode': qr_pil_obj = qrcode.make(item['url'], border=0).resize((item['width'], item['height']), Image.ANTIALIAS) bg.paste(qr_pil_obj,(item['x'],item['y'])) elif item['type'] == 'image': extname = re.search( r'(jpg|png|jpeg)$', item['url']).group() # 加载图片 img = Image.open(item['url']) # 缩放 if (item['width']!= '' and item['height'] != ''): img.resize((item['width'], item['height']), Image.ANTIALIAS) if extname == 'png': bg.paste(img,(item['x'],item['y']), mask=img) else: bg.paste(img,(item['x'],item['y'])) elif item['type'] == 'text': draw = ImageDraw.Draw(bg) ttfront = ImageFont.truetype(item['ttfrontUrl'],item['ttfrontSize']) draw.text((item['x'],item['y']),unicode(item['txt'],"UTF-8"), fill=(0,0,0), font=ttfront) else: print('------------------------------') bg.save(data['outputName'])data = { 'width': 750, 'height': 1334, 'outputName': './out-%s.png' % (str(time.time())), 'list':[{"type":"image","url":"./avatar.jpg","x":10,"y":360,"width":750,"height":1334},{"type":"image","url":"./bg.png","x":0,"y":0,"width":750,"height":750},{"type":"qrcode","url":"https://www.lilnong.top","x":0,"y":0,"width":120,"height":120},{"type":"text","txt":"你这个死宅说话","x":140,"y":560,"ttfrontUrl":"./abc.ttf","ttfrontSize":55},{"type":"text","txt":"还挺搞笑的","x":160,"y":630,"ttfrontUrl":"./abc.ttf","ttfrontSize":55}]}AddMoney(data)长截图这个也是极好,是之前一个 Node 的服务。省时省力。网上查也不少 ...

June 18, 2019 · 1 min · jiezi

利用html2canvas实现移动端上传图片生成海报

原文链接:链接描述使用vue+html2canvas+exif-js github地址 线上demo 主要功能上传图片对图片进行操作:移动、放大、缩小合成海报具体功能:上传图片html: <input type="file" value="" accept="image/*" @click="getPhoto" id="image-input">js getPhoto () { var imageInput = document.querySelector('#image-input') var that = this imageInput.addEventListener('change', function (e) { reads = new FileReader() reads.readAsDataURL(this.files[0]) reads.addEventListener('load', function (e) { that.imgUrl = this.result that.myImg.position.x = 0 that.myImg.position.y = 0 that.myImg.scale = 1 var orientation that.previewImg.addEventListener('load', function () { Exif.getData(that.previewImg, function() { // 获取图像的数据 Exif.getAllTags(this); // 获取图像的全部数据,值以对象的方式返回 orientation = Exif.getTag(this, "Orientation"); // 获取图像的拍摄方向 var rotateCanvas = document.createElement("canvas"), rotateCtx = rotateCanvas.getContext("2d"); // 针对图像方向进行处理 switch (orientation) { case 1 : rotateCanvas.width = that.previewImg.width; rotateCanvas.height = that.previewImg.height; rotateCtx.drawImage(that.previewImg, 0, 0, that.previewImg.width, that.previewImg.height); break; case 6 : // 顺时针 90 度 rotateCanvas.width = that.previewImg.height; rotateCanvas.height = that.previewImg.width; rotateCtx.translate(0, 0); rotateCtx.rotate(90 * Math.PI / 180); rotateCtx.drawImage(that.previewImg, 0, -that.previewImg.height, that.previewImg.width, that.previewImg.height); break; case 8 : rotateCanvas.width = that.previewImg.height; rotateCanvas.height = that.previewImg.width; rotateCtx.translate(0, 0); rotateCtx.rotate(-90 * Math.PI / 180); rotateCtx.drawImage(that.previewImg, -that.previewImg.width, 0, that.previewImg.width, that.previewImg.height); break; case 3 : // 180 度 rotateCanvas.width = that.previewImg.width; rotateCanvas.height = that.previewImg.height; rotateCtx.translate(0, 0); rotateCtx.rotate(Math.PI); rotateCtx.drawImage(that.previewImg, -that.previewImg.width, -that.previewImg.height, that.previewImg.width, that.previewImg.height); break; default : rotateCanvas.width = that.previewImg.width; rotateCanvas.height = that.previewImg.height; rotateCtx.drawImage(that.previewImg, 0, 0, that.previewImg.width, that.previewImg.height); } var rotateBase64 = rotateCanvas.toDataURL("image/jpeg", 0.5); }); }) }) })}移动图片对图片和相框绑定@touchstart @touchmove @touchend ...

May 18, 2019 · 3 min · jiezi

使用html2canvas将页面转成图,用canvas2image下载

之前在网上找到一个用 <a> 的 download属性下载的方法,确实很简单也很方便,但此方法不支持IE,无奈又找到另一方法。使用html2canvas将页面转成图,用canvas2image下载本例使用的版本:html2canvas@1.0.0-alpha.12canvas2image@1.0.5安装npm install html2canvas canvas2image –save引入import html2canvas from ‘html2canvas’;require(’./canvas2image.js’);canvas2image.js 需要改动一下,以便绑在window上(function($){ Canvas2Image = function () { … }}_dataURL 可以用来回显,Canvas2Image.saveAsPNG(canvas) 会直接下载。Canvas2Image提供了下面几种方法:Canvas2Image.saveAsImage(canvasObj, width, height, type)Canvas2Image.saveAsPNG(canvasObj, width, height)Canvas2Image.saveAsJPEG(canvasObj, width, height)Canvas2Image.saveAsGIF(canvasObj, width, height)Canvas2Image.saveAsBMP(canvasObj, width, height)Canvas2Image.convertToImage(canvasObj, width, height, type)Canvas2Image.convertToPNG(canvasObj, width, height)Canvas2Image.convertToJPEG(canvasObj, width, height)Canvas2Image.convertToGIF(canvasObj, width, height)Canvas2Image.convertToBMP(canvasObj, width, height)在vue中可以用$refs 确定DOM;backgroundColor: null,此句可使转出的图没有白边 methods: { toImage() { let _this = this; html2canvas(this.$refs.index,{ backgroundColor: null }).then((canvas) => { let _dataURL = canvas.toDataURL(“image/png”); // _this.dataURL = _dataURL; Canvas2Image.saveAsPNG(canvas) }); }, ...

March 26, 2019 · 1 min · jiezi