网站首页 > 技术文章 正文
浏览器截图方案分析
页面截屏是前端经常遇到的需求,比如页面生成海报,弹窗图片分享等。
以下是我整理三种截图方案:
- html2canvas
- dom-to-image
- webRTC
html2canvas
html2canvas 用的比较广泛的前端截图方案,先将 DOM 一个个 转为 Canvas 然后导出图片(使用 canvas 自带的 toDataUrl、toBobl)即可。使用起来应该是兼容性比较好的方案了,能解决大部分的需求,但是也有一些小问题,如:
- 图片跨域,开启
- CSS 属性错乱
- 遇到 canvas 元素导出后为透明色。
大部分问题还是可以通过配置和百度解决的
const getDomImg = (eleId) => { html2canvas(document.getElementById(eleId), { //superMap整个页面的节点
backgroundColor: null, //画出来的图片有白色的边框,不要可设置背景为透明色(null)
allowTaint: true, useCORS: true, //支持图片跨域
scale: 1, //设置放大的倍数
})
.then((canvas) => { //截图用img元素承装,显示在页面的上
let img = new Image();
img.src = canvas.toDataURL("image/jpg"); // toDataURL :图片格式转成 base64
// 直接下载
let a = document.createElement("a");
a.href = canvas.toDataURL("image/jpeg");
a.download = "test";
a.click();
})
.catch((err) => { console.log("html2canvas err", err);
});
};
dom-to-image
使用 svg,通过 createObjectURL 或 encodeURIComponent 处理 svg 得到图像资源,可以把 svg 绘制到 canvas。
dom-to-image-more 是dom-to-image的升级版 将 HTMl 放到 SVG 里,然后创建一个以 SVG 作为源的 Image 元素
但是也有一些问题如: svg 中不允许外部资源(js,css,img 的 url 等),svg 中不支持执行 js,需要经过处理,也不能完全还原
const getDomImg = (eleId) => {
domtoimage
.toPng(document.getElementById(eleId))
.then(function (dataUrl) { let a = document.createElement("a");
a.href = dataUrl;
a.download = "test";
a.click();
})
.catch(function (error) { console.error("生成失败", error);
});
};
webRTC
使用浏览器原生 API——webERT中的getDisplayMedia可以将窗口中的资源以录屏方式从其中拿出一帧,但是需要用户授权和做一些窗口选择,相比于前两种方案做不到默认截图。
但是优势也很明显,就是不会有什么样式错乱、图片跨域等问题。因为使用的浏览器原生方法,基本上用户看到是什么样子,截图出来就是什么样子,1: 1 还原。
function getDomImg(videoId: string) { const videoElem: any = document.getElementById(videoId); const displayMediaOptions = { audio: false, video: { width: window.screen.width, height: window.screen.height }, // cursor: "always"
};
navigator.mediaDevices
.getDisplayMedia(displayMediaOptions)
.then((stream) => {
videoElem.srcObject = stream; setTimeout(() => { var canvas = document.createElement("canvas");
canvas.width = videoElem.clientWidth;
canvas.height = videoElem.clientHeight;
canvas
.getContext("2d")
.drawImage(
videoElem, 0, 0, window.screen.width, window.screen.height, 0, 0,
canvas.width,
canvas.height
); var dataURL = canvas.toDataURL("image/webp"); let a = document.createElement("a");
a.href = dataURL;
a.download = "test";
a.click(); let tracks = videoElem.srcObject.getTracks();
tracks.forEach((track) => track.stop());
videoElem.srcObject = null;
}, 200);
})
.finally(() => {});
}
需要在代码中放入一个 Video 标签
<video id="video"></video>
截图后上传
如果有将截图上传的需求,可以转换一个格式在上传。
canvas 导出的 base64 是不可以直接上传到服务器的,所以需要转一下格式,我这边找了转换 Blob 和 file 两种格式的方法。我用的将图片转为 Blob后上传的。
- base64转化为Blob对象
// function convertBase64ToBlob(imageEditorBase64) { var base64Arr = imageEditorBase64.split(","); var imgtype = ""; var base64String = ""; if (base64Arr.length > 1) { //如果是图片base64,去掉头信息
base64String = base64Arr[1];
imgtype = base64Arr[0].substring(
base64Arr[0].indexOf(":") + 1,
base64Arr[0].indexOf(";")
);
} // 将base64解码
var bytes = atob(base64String); //var bytes = base64;
var bytesCode = new ArrayBuffer(bytes.length); // 转换为类型化数组
var byteArray = new Uint8Array(bytesCode); // 将base64转换为ascii码
for (var i = 0; i < bytes.length; i++) {
byteArray[i] = bytes.charCodeAt(i);
} // 生成Blob对象(文件对象)
return new Blob([bytesCode], { type: imgtype });
}
- base64 转 formData
function base64ToFile(data, fileName) { const dataArr = data.split(","); const byteString = atob(dataArr[1]); const options: any = { type: "image/jpeg", endings: "native",
}; const u8Arr = new Uint8Array(byteString.length); for (let i = 0; i < byteString.length; i++) {
u8Arr[i] = byteString.charCodeAt(i);
} let formData = new FormData(); let fileOfBlob = new File([u8Arr], fileName + ".jpg", options); //返回文件流
formData.append("file", fileOfBlob); console.log("file", formData); debugger; return formData;
}
示例
GitHub:https://github.com/AnsonZnl/w...
代码基于 Create React App 演示三种截图方法的基本使用方式。
参考
- 史上最详细浏览器端网页截图方案解析
- 一款实用的前端截图工具
javascript
- 上一篇: Web前端就业有哪些必备的技能和知识点?
- 下一篇: 在vue里实现页面截图功能
猜你喜欢
- 2024-11-23 VC.NET全屏截屏或鼠标拖动出区域,截图效果「附源码」
- 2024-11-23 Star 17.3k!给它一张屏幕截图,即可一键克隆网页!
- 2024-11-23 一个好的前端年薪会有多少钱?
- 2024-11-23 57挑战之53,python实现客户端+服务端
- 2024-11-23 6个月转行成功WEB前端工程师的秘诀在这里
- 2024-11-23 分享 12 个超级实用的前端工具,可能就是你一直在寻找的!
- 2024-11-23 超级实用的截图工具分享—Snipaste
- 2024-11-23 前端革命时刻:前端代码是怎样智能生成的-图像分离篇
- 2024-11-23 推荐给前端开发的 5 款 Chrome 扩展
- 2024-11-23 这4个神器,帮你自动美化生成好看的网页截图
你 发表评论:
欢迎- 07-10Oracle 与 Google Cloud 携手大幅扩展多云服务
- 07-10分享收藏的 oracle 11.2.0.4各平台的下载地址
- 07-10Oracle 和 Microsoft 推出 Oracle Exadata 数据库服务
- 07-10Oracle Database@Azure 推进到南美等新区域并增加了新服务
- 07-10Oracle宣布推出 Oracle Database@AWS 的有限预览版
- 07-10Oracle与Nextcloud合作,推出主权云上的安全协作平台
- 07-10NodeRED魔改版连接MsSql、PostgreSQL、MySQL、OracleDB存储无忧
- 07-10对于企业数据云备份,“多备份”承诺的是成本更低,管理更高效#36氪开放日深圳站#
- 602℃几个Oracle空值处理函数 oracle处理null值的函数
- 594℃Oracle分析函数之Lag和Lead()使用
- 582℃0497-如何将Kerberos的CDH6.1从Oracle JDK 1.8迁移至OpenJDK 1.8
- 579℃Oracle数据库的单、多行函数 oracle执行多个sql语句
- 574℃Oracle 12c PDB迁移(一) oracle迁移到oceanbase
- 567℃【数据统计分析】详解Oracle分组函数之CUBE
- 554℃最佳实践 | 提效 47 倍,制造业生产 Oracle 迁移替换
- 548℃Oracle有哪些常见的函数? oracle中常用的函数
- 最近发表
-
- Oracle 与 Google Cloud 携手大幅扩展多云服务
- 分享收藏的 oracle 11.2.0.4各平台的下载地址
- Oracle 和 Microsoft 推出 Oracle Exadata 数据库服务
- Oracle Database@Azure 推进到南美等新区域并增加了新服务
- Oracle宣布推出 Oracle Database@AWS 的有限预览版
- Oracle与Nextcloud合作,推出主权云上的安全协作平台
- NodeRED魔改版连接MsSql、PostgreSQL、MySQL、OracleDB存储无忧
- 对于企业数据云备份,“多备份”承诺的是成本更低,管理更高效#36氪开放日深圳站#
- 解读丨《归档文件整理规则》— 电子文件元数据存储
- Data Guard跳归档恢复的实践(dataguard failover)
- 标签列表
-
- 前端设计模式 (75)
- 前端性能优化 (51)
- 前端模板 (66)
- 前端跨域 (52)
- 前端缓存 (63)
- 前端aes加密 (58)
- 前端脚手架 (56)
- 前端md5加密 (54)
- 前端路由 (61)
- 前端数组 (73)
- 前端js面试题 (50)
- 前端定时器 (59)
- 前端获取当前时间 (50)
- Oracle RAC (76)
- oracle恢复 (77)
- oracle 删除表 (52)
- oracle 用户名 (80)
- oracle 工具 (55)
- oracle 内存 (55)
- oracle 导出表 (62)
- oracle约束 (54)
- oracle 中文 (51)
- oracle链接 (54)
- oracle的函数 (57)
- 前端调试 (52)
本文暂时没有评论,来添加一个吧(●'◡'●)