10-ArcGIS For JavaScript -- 三维场景导出为图片(PNG/JPEG)

打印 上一主题 下一主题

主题 1808|帖子 1808|积分 5424


前言

三维场景开发过程中,时常会出现必要保存当前场景的内容,去做一些分析或者场景展示。如果使用计算机自带的截图功能,只能将当前的页面截取到计算机本地,不能直接提供给程序去使用。
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、以当前视图相同的分辨率举行截图

  1. view.takeScreenshot().then(function(screenshot) {
  2.   let imageElement = document.getElementById("screenshotImage");
  3.   imageElement.src = screenshot.dataUrl;
  4. });
复制代码
2、从当前视图创建一个方形缩略图

  1. let options = {
  2.   width: 200,
  3.   height: 200
  4. };
  5. view.takeScreenshot(options).then(function(screenshot) {
  6.   let imageElement = document.getElementById("screenshotImage");
  7.   imageElement.src = screenshot.dataUrl;
  8. });
复制代码
3、取一个高分辨率的方形截图

  1. let options = {
  2.   width: 2048,
  3.   height: 2048
  4. };
  5. view.takeScreenshot(options).then(function(screenshot) {
  6.   let imageElement = document.getElementById("screenshotImage");
  7.   imageElement.src = screenshot.dataUrl;
  8. });
复制代码
3、在视图中心截取一个小地区的屏幕截图

  1. // 计算视图的大小,不包括padding的部分
  2. let padding = view.padding;
  3. let innerWidth = view.width - padding.left - padding.right;
  4. let innerHeight = view.height - padding.top - padding.bottom;
  5. // 期望的区域大小
  6. let width = 200;
  7. let height = 200;
  8. let options = {
  9.   area: {
  10.     x: (innerWidth - width) / 2,
  11.     y: (innerHeight - height) / 2,
  12.     width: width,
  13.     height: height
  14.   }
  15. };
  16. view.takeScreenshot(options).then(function(screenshot) {
  17.   let imageElement = document.getElementById("screenshotImage");
  18.   imageElement.src = screenshot.dataUrl;
  19. });
复制代码
三、完成代码

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.     <meta charset="UTF-8">
  5.     <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.     <title>Document</title>
  7.     <link rel="stylesheet" href="https://js.arcgis.com/4.30/esri/themes/light/main.css" />
  8.     <script src="https://js.arcgis.com/4.30/"></script>
  9.     <style>
  10.         html,
  11.         body,
  12.         #viewDiv {
  13.             height: 100%;
  14.             width: 100%;
  15.             margin: 0;
  16.             padding: 0;
  17.         }
  18.         .screenshotDiv {
  19.             position: absolute;
  20.             top: 0;
  21.             left: 0;
  22.             right: 0;
  23.             bottom: 0;
  24.             text-align: center;
  25.             background-color: rgba(255, 255, 255, 0.8);
  26.         }
  27.         .screenshotDiv img {
  28.             border: 10px solid white;
  29.             box-shadow: 2px 2px 5px 0 rgba(0, 0, 0, 0.5);
  30.         }
  31.         .screenshotDiv>* {
  32.             margin: 0.5em;
  33.         }
  34.         .actionButton {
  35.             padding: 0.4em;
  36.             color: black;
  37.             border: 1px solid #5c5e5e;
  38.             text-align: center;
  39.             background-color: #f1efef;
  40.             cursor: pointer;
  41.             width: 100px;
  42.             border-radius: 3px;
  43.             font-size: 16px;
  44.         }
  45.         .actionButton:hover,
  46.         .actionButton:focus {
  47.             background: #0079c1;
  48.             color: white;
  49.         }
  50.         .closeBtn {
  51.             display: inherit;
  52.             margin: auto;
  53.         }
  54.         .title {
  55.             position: absolute;
  56.             top: 20px;
  57.             width: 600px;
  58.             left: calc(50% - 300px);
  59.             background: #ffffff99;
  60.             padding: 5px;
  61.             border-radius: 3px;
  62.         }
  63.         .hide{
  64.             display: none;
  65.         }
  66.     </style>
  67.     <script>
  68.         require([
  69.             'esri/geometry/Point',
  70.             "esri/geometry/SpatialReference",
  71.             "esri/geometry/Mesh",
  72.             "esri/views/SceneView",
  73.             "esri/Map",
  74.             "esri/Graphic",
  75.             "esri/symbols/FillSymbol3DLayer",
  76.             "esri/symbols/MeshSymbol3D",
  77.             "esri/geometry/support/MeshMaterial",
  78.             "esri/geometry/support/MeshLocalVertexSpace",
  79.             "esri/layers/IntegratedMeshLayer"
  80.         ], (Point, SpatialReference, Mesh, SceneView, Map,
  81.             Graphic, FillSymbol3DLayer, MeshSymbol3D, MeshMaterial, MeshLocalVertexSpace, IntegratedMeshLayer) => {
  82.             let layer = new IntegratedMeshLayer({
  83.                 url: "https://tiles.arcgis.com/tiles/cFEFS0EWrhfDeVw9/arcgis/rest/services/Utrecht_Buildings_2021/SceneServer"
  84.             })
  85.             let map = new Map({
  86.                 layers: [layer],
  87.                 basemap: 'satellite'
  88.             })
  89.             let center = [116.4074, 39.9042, 300];
  90.             let view = new SceneView({
  91.                 container: 'viewDiv',
  92.                 map,
  93.             })
  94.             view.when(function () {
  95.                 view.extent = layer.fullExtent;
  96.             })
  97.             const screenshotBtn = document.getElementById("screenshotBtn");
  98.             // const maskDiv = document.getElementById("maskDiv");
  99.             let screenshotDiv = document.getElementById("screenshotDiv");
  100.             const closeBtn = document.getElementById("closeBtn");
  101.             screenshotDiv.classList.add("hide");
  102.             view.ui.empty("top-right");
  103.             view.ui.add(screenshotBtn, "top-right");
  104.             let that = this;
  105.             screenshotBtn.addEventListener("click", () => {
  106.                 let self = that;
  107.                 let area = null;
  108.                 area = {
  109.                     x: view.canvas.clientLeft,
  110.                     y: view.canvas.clientTop,
  111.                     height: view.height,
  112.                     width: view.width
  113.                 }
  114.                 //"jpg"|"png"
  115.                 view.takeScreenshot({ area: area, format: "png" })
  116.                     .then((screenshot) => {
  117.                         console.log(screenshot);//screenshot.dataUrl为base64信息
  118.                         // let blob = self.base64ToBlob(screenshot.dataUrl, 'png')
  119.                         // self.download("test.png", blob);
  120.                         downloadFile(screenshot.dataUrl, 'download', '.png');
  121.                         showPreview(screenshot);//可以删除,只是为了展示截图信息
  122.                     })
  123.             });
  124.             /**
  125.              * desc: base64对象转blob文件对象
  126.              * @param urlData  :数据的base64对象
  127.              * @param type  :类型 png,pdf,doc,mp3等;
  128.              * @returns {Blob}:Blob文件对象
  129.              */
  130.             function base64ToBlob(urlData, type) {
  131.                 let arr = urlData.split(',');
  132.                 let array = arr[0].match(/:(.*?);/);
  133.                 let mime = (array && array.length > 1 ? array[1] : type) || type;
  134.                 // 去掉url的头,并转化为byte
  135.                 let bytes = window.atob(arr[2]);
  136.                 // 处理异常,将ascii码小于0的转换为大于0
  137.                 let ab = new ArrayBuffer(bytes.length);
  138.                 // 生成视图(直接针对内存):8位无符号整数,长度1个字节
  139.                 let ia = new Uint8Array(ab);
  140.                 for (let i = 0; i < bytes.length; i++) {
  141.                     ia[i] = bytes.charCodeAt(i);
  142.                 }
  143.                 return new Blob([ab], {
  144.                     type: mime
  145.                 });
  146.             }
  147.             /**
  148.            * desc: 下载导出文件
  149.            * @param blob  :返回数据的blob对象或链接
  150.            * @param fileName  :下载后文件名标记
  151.            * @param fileType  :文件类 word(docx) excel(xlsx) ppt等
  152.            */
  153.            function downloadExportFile(blob, fileName, fileType) {
  154.                 let downloadElement = document.createElement('a');
  155.                 let href = blob;
  156.                 if (typeof blob == 'string') {
  157.                     downloadElement.target = '_blank';
  158.                 } else {
  159.                     href = window.URL.createObjectURL(blob); //创建下载的链接
  160.                 }
  161.                 downloadElement.href = href;
  162.                 downloadElement.download = fileName + '.' + fileType; //下载后文件名
  163.                 document.body.appendChild(downloadElement);
  164.                 downloadElement.click(); //触发点击下载
  165.                 document.body.removeChild(downloadElement); //下载完成移除元素
  166.                 if (typeof blob != 'string') {
  167.                     window.URL.revokeObjectURL(href); //释放掉blob对象
  168.                 }
  169.             }
  170.             /**
  171.              * desc: base64转文件并下载
  172.              * @param base64 {String} : base64数据
  173.              * @param fileType {String} : 要导出的文件类型png,pdf,doc,mp3等
  174.              * @param fileName {String} : 文件名
  175.              */
  176.              function downloadFile(base64, fileName, fileType) {
  177.                 let typeHeader = 'data:application/' + fileType + ';base64,' // 定义base64 头部文件类型
  178.                 let converedBase64 = typeHeader + base64;  // 拼接最终的base64
  179.                 let blob = base64ToBlob(converedBase64, fileType)  // 转成blob对象
  180.                 downloadExportFile(blob, fileName, fileType) // 下载文件
  181.             }
  182.             function showPreview(screenshot) {
  183.                 screenshotDiv.classList.remove("hide");
  184.                 // add the screenshot dataUrl as the src of an image element
  185.                 const screenshotImage = document.getElementsByClassName(
  186.                     "js-screenshot-image"
  187.                 )[0];
  188.                 screenshotImage.width = screenshot.data.width * 0.3;
  189.                 screenshotImage.height = screenshot.data.height * 0.3;
  190.                 screenshotImage.src = screenshot.dataUrl;
  191.             }
  192.             document.getElementById('closeBtn').addEventListener('click', function () {
  193.                 screenshotDiv.classList.add("hide");
  194.             })
  195.         })
  196.     </script>
  197. </head>
  198. <body>
  199.     <div id="viewDiv">
  200.         <button id="screenshotBtn" class="esri-widget actionButton" aria-label="Select screenshot area"
  201.             title="Select screenshot area">
  202.             截图
  203.         </button>
  204.         <div id="screenshotDiv" class="screenshotDiv">
  205.             <img class="js-screenshot-image" />
  206.             <button id="closeBtn" class="closeBtn action-button" aria-label="Back to webscene" title="Back to webscene">
  207.                 返回到web场景
  208.             </button>
  209.         </div>
  210.     </div>
  211. </body>
  212. </html>
复制代码
四、效果图




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

道家人

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表