前言
三维场景开发过程中,时常会出现必要保存当前场景的内容,去做一些分析或者场景展示。如果使用计算机自带的截图功能,只能将当前的页面截取到计算机本地,不能直接提供给程序去使用。
ArcGIS For JavaScript 的SceneView对象中提供了一个takeScreenshot函数,它可以创建当前视图的屏幕截图。屏幕截图仅包罗在画布上渲染的元素 (全部地理元素),但不包罗覆盖的 DOM 元素 (UI、弹出窗口等)。默认环境下,会创建整个视图的屏幕截图。差别的选项允许创建差别类型的屏幕截图,包罗以差别的纵横比、差别的分辨率举行屏幕截图和创建缩略图。相关参数可以参考官网。
一、takeScreenshot参数
- format:默认值为png,生成的编码数据 url 的格式。可能值:“jpg”|“png”。
- quality:默认值为98,格式为 jpg 时编码图像的质量 (0 - 100)。
- width:屏幕截图的宽度 (默以为地区宽度)。如果未指定,高度将根据屏幕截图地区的纵横比主动得出。
- height:屏幕截图的高度 (默以为地区高度)。如果未指定,宽度将根据屏幕截图地区的纵横比主动得出。
- area:指定是否截取视图特定地区的屏幕截图。地区坐标相对于内边距视图的原点 (请参阅 padding),并将裁剪为视图巨细。默以为整个视图 (不包罗内边距)。
- ignorePadding:指示是否应忽略视图内边距。将此属性设置为 true 以允许在屏幕截图中包含内边距地区。
二、示例
1、以当前视图相同的分辨率举行截图
- view.takeScreenshot().then(function(screenshot) {
- let imageElement = document.getElementById("screenshotImage");
- imageElement.src = screenshot.dataUrl;
- });
复制代码 2、从当前视图创建一个方形缩略图
- let options = {
- width: 200,
- height: 200
- };
- view.takeScreenshot(options).then(function(screenshot) {
- let imageElement = document.getElementById("screenshotImage");
- imageElement.src = screenshot.dataUrl;
- });
复制代码 3、取一个高分辨率的方形截图
- let options = {
- width: 2048,
- height: 2048
- };
- view.takeScreenshot(options).then(function(screenshot) {
- let imageElement = document.getElementById("screenshotImage");
- imageElement.src = screenshot.dataUrl;
- });
复制代码 3、在视图中心截取一个小地区的屏幕截图
- // 计算视图的大小,不包括padding的部分
- let padding = view.padding;
- let innerWidth = view.width - padding.left - padding.right;
- let innerHeight = view.height - padding.top - padding.bottom;
- // 期望的区域大小
- let width = 200;
- let height = 200;
- let options = {
- area: {
- x: (innerWidth - width) / 2,
- y: (innerHeight - height) / 2,
- width: width,
- height: height
- }
- };
- view.takeScreenshot(options).then(function(screenshot) {
- let imageElement = document.getElementById("screenshotImage");
- imageElement.src = screenshot.dataUrl;
- });
复制代码 三、完成代码
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <title>Document</title>
- <link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css" />
- <script src="https://js.arcgis.com/4.30/"></script>
- <style>
- html,
- body,
- #viewDiv {
- height: 100%;
- width: 100%;
- margin: 0;
- padding: 0;
- }
- .screenshotDiv {
- position: absolute;
- top: 0;
- left: 0;
- right: 0;
- bottom: 0;
- text-align: center;
- background-color: rgba(255, 255, 255, 0.8);
- }
- .screenshotDiv img {
- border: 10px solid white;
- box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.5);
- }
- .screenshotDiv>* {
- margin: 0.5em;
- }
- .actionButton {
- padding: 0.4em;
- color: black;
- border: 1px solid #5c5e5e;
- text-align: center;
- background-color: #f1efef;
- cursor: pointer;
- width: 100px;
- border-radius: 3px;
- font-size: 16px;
- }
- .actionButton:hover,
- .actionButton:focus {
- background: #0079c1;
- color: white;
- }
- .closeBtn {
- display: inherit;
- margin: auto;
- }
- .title {
- position: absolute;
- top: 20px;
- width: 600px;
- left: calc(50% - 300px);
- background: #ffffff99;
- padding: 5px;
- border-radius: 3px;
- }
- .hide{
- display: none;
- }
- </style>
- <script>
- require([
- 'esri/geometry/Point',
- "esri/geometry/SpatialReference",
- "esri/geometry/Mesh",
- "esri/views/SceneView",
- "esri/Map",
- "esri/Graphic",
- "esri/symbols/FillSymbol3DLayer",
- "esri/symbols/MeshSymbol3D",
- "esri/geometry/support/MeshMaterial",
- "esri/geometry/support/MeshLocalVertexSpace",
- "esri/layers/IntegratedMeshLayer"
- ], (Point, SpatialReference, Mesh, SceneView, Map,
- Graphic, FillSymbol3DLayer, MeshSymbol3D, MeshMaterial, MeshLocalVertexSpace, IntegratedMeshLayer) => {
- let layer = new IntegratedMeshLayer({
- url: "https://tiles.arcgis.com/tiles/cFEFS0EWrhfDeVw9/arcgis/rest/services/Utrecht_Buildings_2021/SceneServer"
- })
- let map = new Map({
- layers: [layer],
- basemap: 'satellite'
- })
- let center = [116.4074, 39.9042, 300];
- let view = new SceneView({
- container: 'viewDiv',
- map,
- })
- view.when(function () {
- view.extent = layer.fullExtent;
- })
- const screenshotBtn = document.getElementById("screenshotBtn");
- // const maskDiv = document.getElementById("maskDiv");
- let screenshotDiv = document.getElementById("screenshotDiv");
- const closeBtn = document.getElementById("closeBtn");
- screenshotDiv.classList.add("hide");
- view.ui.empty("top-right");
- view.ui.add(screenshotBtn, "top-right");
- let that = this;
- screenshotBtn.addEventListener("click", () => {
- let self = that;
- let area = null;
- area = {
- x: view.canvas.clientLeft,
- y: view.canvas.clientTop,
- height: view.height,
- width: view.width
- }
- //"jpg"|"png"
- view.takeScreenshot({ area: area, format: "png" })
- .then((screenshot) => {
- console.log(screenshot);//screenshot.dataUrl为base64信息
- // let blob = self.base64ToBlob(screenshot.dataUrl, 'png')
- // self.download("test.png", blob);
- downloadFile(screenshot.dataUrl, 'download', '.png');
- showPreview(screenshot);//可以删除,只是为了展示截图信息
- })
- });
- /**
- * desc: base64对象转blob文件对象
- * @param urlData :数据的base64对象
- * @param type :类型 png,pdf,doc,mp3等;
- * @returns {Blob}:Blob文件对象
- */
- function base64ToBlob(urlData, type) {
- let arr = urlData.split(',');
- let array = arr[0].match(/:(.*?);/);
- let mime = (array && array.length > 1 ? array[1] : type) || type;
- // 去掉url的头,并转化为byte
- let bytes = window.atob(arr[2]);
- // 处理异常,将ascii码小于0的转换为大于0
- let ab = new ArrayBuffer(bytes.length);
- // 生成视图(直接针对内存):8位无符号整数,长度1个字节
- let ia = new Uint8Array(ab);
- for (let i = 0; i < bytes.length; i++) {
- ia[i] = bytes.charCodeAt(i);
- }
- return new Blob([ab], {
- type: mime
- });
- }
- /**
- * desc: 下载导出文件
- * @param blob :返回数据的blob对象或链接
- * @param fileName :下载后文件名标记
- * @param fileType :文件类 word(docx) excel(xlsx) ppt等
- */
- function downloadExportFile(blob, fileName, fileType) {
- let downloadElement = document.createElement('a');
- let href = blob;
- if (typeof blob == 'string') {
- downloadElement.target = '_blank';
- } else {
- href = window.URL.createObjectURL(blob); //创建下载的链接
- }
- downloadElement.href = href;
- downloadElement.download = fileName + '.' + fileType; //下载后文件名
- document.body.appendChild(downloadElement);
- downloadElement.click(); //触发点击下载
- document.body.removeChild(downloadElement); //下载完成移除元素
- if (typeof blob != 'string') {
- window.URL.revokeObjectURL(href); //释放掉blob对象
- }
- }
- /**
- * desc: base64转文件并下载
- * @param base64 {String} : base64数据
- * @param fileType {String} : 要导出的文件类型png,pdf,doc,mp3等
- * @param fileName {String} : 文件名
- */
- function downloadFile(base64, fileName, fileType) {
- let typeHeader = 'data:application/' + fileType + ';base64,' // 定义base64 头部文件类型
- let converedBase64 = typeHeader + base64; // 拼接最终的base64
- let blob = base64ToBlob(converedBase64, fileType) // 转成blob对象
- downloadExportFile(blob, fileName, fileType) // 下载文件
- }
- function showPreview(screenshot) {
- screenshotDiv.classList.remove("hide");
- // add the screenshot dataUrl as the src of an image element
- const screenshotImage = document.getElementsByClassName(
- "js-screenshot-image"
- )[0];
- screenshotImage.width = screenshot.data.width * 0.3;
- screenshotImage.height = screenshot.data.height * 0.3;
- screenshotImage.src = screenshot.dataUrl;
- }
- document.getElementById('closeBtn').addEventListener('click', function () {
- screenshotDiv.classList.add("hide");
- })
- })
- </script>
- </head>
- <body>
- <div id="viewDiv">
- <button id="screenshotBtn" class="esri-widget actionButton" aria-label="Select screenshot area"
- title="Select screenshot area">
- 截图
- </button>
- <div id="screenshotDiv" class="screenshotDiv">
- <img class="js-screenshot-image" />
- <button id="closeBtn" class="closeBtn action-button" aria-label="Back to webscene" title="Back to webscene">
- 返回到web场景
- </button>
- </div>
- </div>
- </body>
- </html>
复制代码 四、效果图
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |