道家人 发表于 2025-3-28 13:48:46

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

前言

三维场景开发过程中,时常会出现必要保存当前场景的内容,去做一些分析或者场景展示。如果使用计算机自带的截图功能,只能将当前的页面截取到计算机本地,不能直接提供给程序去使用。
ArcGIS For JavaScript 的SceneView对象中提供了一个takeScreenshot函数,它可以创建当前视图的屏幕截图。屏幕截图仅包罗在画布上渲染的元素 (全部地理元素),但不包罗覆盖的 DOM 元素 (UI、弹出窗口等)。默认环境下,会创建整个视图的屏幕截图。差别的选项允许创建差别类型的屏幕截图,包罗以差别的纵横比、差别的分辨率举行屏幕截图和创建缩略图。相关参数可以参考官网。
https://i-blog.csdnimg.cn/direct/11406f7379d3431c885a5405c12d9df6.png
一、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: ,
                basemap: 'satellite'
            })
            let center = ;

            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.match(/:(.*?);/);
                let mime = (array && array.length > 1 ? array : type) || type;
                // 去掉url的头,并转化为byte
                let bytes = window.atob(arr);
                // 处理异常,将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 = bytes.charCodeAt(i);
                }
                return new Blob(, {
                  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"
                );
                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>
四、效果图

https://i-blog.csdnimg.cn/direct/b94a69ca4e54451da2c5200f39bab468.png
https://i-blog.csdnimg.cn/direct/bec6571491a1497cb19a09bcf10f6477.png

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 10-ArcGIS For JavaScript -- 三维场景导出为图片(PNG/JPEG)