cesium-场景出图场景截屏导出图片或pdf

news2024/11/26 14:58:50

cesium把当前的场景截图,下载图片或pdf

安装

npm install canvas2image --save
npm i jspdf -S

如果安装的插件Canvas2Image不好用,可自建js

Canvas2Image.js
/**
 * covert canvas to image
 * and save the image file
 */
const Canvas2Image = (function () {
	// check if support sth.
	const $support = (function () {
		const canvas = document.createElement("canvas"),
			ctx = canvas.getContext("2d");

		return {
			canvas: !!ctx,
			imageData: !!ctx.getImageData,
			dataURL: !!canvas.toDataURL,
			btoa: !!window.btoa,
		};
	})();

	const downloadMime = "image/octet-stream";

	function scaleCanvas(canvas, width, height) {
		const w = canvas.width,
			h = canvas.height;
		if (width === undefined) {
			width = w;
		}
		if (height === undefined) {
			height = h;
		}

		let retCanvas = document.createElement("canvas");
		let retCtx = retCanvas.getContext("2d");
		retCanvas.width = width;
		retCanvas.height = height;
		retCtx.drawImage(canvas, 0, 0, w, h, 0, 0, width, height);
		return retCanvas;
	}

	function getDataURL(canvas, type, width, height) {
		canvas = scaleCanvas(canvas, width, height);
		return canvas.toDataURL(type);
	}

	// save file to local with file name and file type
	function saveFile(strData, fileType, fileName = "name") {
		// document.location.href = strData;
		let saveLink = document.createElement("a");
		// download file name
		saveLink.download = fileName + "." + fileType;
		// download file data
		saveLink.href = strData;
		// start download
		saveLink.click();
	}

	function genImage(strData) {
		let img = document.createElement("img");
		img.src = strData;
		return img;
	}

	function fixType(type) {
		type = type.toLowerCase().replace(/jpg/i, "jpeg");
		const r = type.match(/png|jpeg|bmp|gif/)[0];
		return "image/" + r;
	}

	function encodeData(data) {
		if (!window.btoa) {
			// eslint-disable-next-line no-throw-literal
			throw "btoa undefined";
		}
		let str = "";
		if (typeof data == "string") {
			str = data;
		} else {
			for (let i = 0; i < data.length; i++) {
				str += String.fromCharCode(data[i]);
			}
		}

		return btoa(str);
	}

	function getImageData(canvas) {
		const w = canvas.width,
			h = canvas.height;
		return canvas.getContext("2d").getImageData(0, 0, w, h);
	}

	function makeURI(strData, type) {
		return "data:" + type + ";base64," + strData;
	}

	/**
	 * create bitmap image
	 * 按照规则生成图片响应头和响应体
	 */
	const genBitmapImage = function (oData) {
		//
		// BITMAPFILEHEADER: http://msdn.microsoft.com/en-us/library/windows/desktop/dd183374(v=vs.85).aspx
		// BITMAPINFOHEADER: http://msdn.microsoft.com/en-us/library/dd183376.aspx
		//

		const biWidth = oData.width;
		const biHeight = oData.height;
		const biSizeImage = biWidth * biHeight * 3;
		const bfSize = biSizeImage + 54; // total header size = 54 bytes

		//
		//  typedef struct tagBITMAPFILEHEADER {
		//  	WORD bfType;
		//  	DWORD bfSize;
		//  	WORD bfReserved1;
		//  	WORD bfReserved2;
		//  	DWORD bfOffBits;
		//  } BITMAPFILEHEADER;
		//
		const BITMAPFILEHEADER = [
			// WORD bfType -- The file type signature; must be "BM"
			0x42,
			0x4d,
			// DWORD bfSize -- The size, in bytes, of the bitmap file
			bfSize & 0xff,
			(bfSize >> 8) & 0xff,
			(bfSize >> 16) & 0xff,
			(bfSize >> 24) & 0xff,
			// WORD bfReserved1 -- Reserved; must be zero
			0,
			0,
			// WORD bfReserved2 -- Reserved; must be zero
			0,
			0,
			// DWORD bfOffBits -- The offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to the bitmap bits.
			54,
			0,
			0,
			0,
		];

		//
		//  typedef struct tagBITMAPINFOHEADER {
		//  	DWORD biSize;
		//  	LONG  biWidth;
		//  	LONG  biHeight;
		//  	WORD  biPlanes;
		//  	WORD  biBitCount;
		//  	DWORD biCompression;
		//  	DWORD biSizeImage;
		//  	LONG  biXPelsPerMeter;
		//  	LONG  biYPelsPerMeter;
		//  	DWORD biClrUsed;
		//  	DWORD biClrImportant;
		//  } BITMAPINFOHEADER, *PBITMAPINFOHEADER;
		//
		const BITMAPINFOHEADER = [
			// DWORD biSize -- The number of bytes required by the structure
			40,
			0,
			0,
			0,
			// LONG biWidth -- The width of the bitmap, in pixels
			biWidth & 0xff,
			(biWidth >> 8) & 0xff,
			(biWidth >> 16) & 0xff,
			(biWidth >> 24) & 0xff,
			// LONG biHeight -- The height of the bitmap, in pixels
			biHeight & 0xff,
			(biHeight >> 8) & 0xff,
			(biHeight >> 16) & 0xff,
			(biHeight >> 24) & 0xff,
			// WORD biPlanes -- The number of planes for the target device. This value must be set to 1
			1,
			0,
			// WORD biBitCount -- The number of bits-per-pixel, 24 bits-per-pixel -- the bitmap
			// has a maximum of 2^24 colors (16777216, Truecolor)
			24,
			0,
			// DWORD biCompression -- The type of compression, BI_RGB (code 0) -- uncompressed
			0,
			0,
			0,
			0,
			// DWORD biSizeImage -- The size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps
			biSizeImage & 0xff,
			(biSizeImage >> 8) & 0xff,
			(biSizeImage >> 16) & 0xff,
			(biSizeImage >> 24) & 0xff,
			// LONG biXPelsPerMeter, unused
			0,
			0,
			0,
			0,
			// LONG biYPelsPerMeter, unused
			0,
			0,
			0,
			0,
			// DWORD biClrUsed, the number of color indexes of palette, unused
			0,
			0,
			0,
			0,
			// DWORD biClrImportant, unused
			0,
			0,
			0,
			0,
		];

		const iPadding = (4 - ((biWidth * 3) % 4)) % 4;

		const aImgData = oData.data;

		let strPixelData = "";
		const biWidth4 = biWidth << 2;
		let y = biHeight;
		const fromCharCode = String.fromCharCode;

		do {
			const iOffsetY = biWidth4 * (y - 1);
			let strPixelRow = "";
			for (let x = 0; x < biWidth; x++) {
				const iOffsetX = x << 2;
				strPixelRow +=
					fromCharCode(aImgData[iOffsetY + iOffsetX + 2]) +
					fromCharCode(aImgData[iOffsetY + iOffsetX + 1]) +
					fromCharCode(aImgData[iOffsetY + iOffsetX]);
			}

			for (let c = 0; c < iPadding; c++) {
				strPixelRow += String.fromCharCode(0);
			}

			strPixelData += strPixelRow;
		} while (--y);

		return (
			encodeData(BITMAPFILEHEADER.concat(BITMAPINFOHEADER)) +
			encodeData(strPixelData)
		);
	};

	/**
	 * saveAsImage
	 * @param canvas canvasElement
	 * @param width {String} image type
	 * @param height {Number} [optional] png width
	 * @param type {string} [optional] png height
	 * @param fileName {String} image name
	 */
	const saveAsImage = function (canvas, width, height, type, fileName) {
		// save file type
		const fileType = type;
		if ($support.canvas && $support.dataURL) {
			if (typeof canvas == "string") {
				canvas = document.getElementById(canvas);
			}
			if (type === undefined) {
				type = "png";
			}
			type = fixType(type);
			if (/bmp/.test(type)) {
				const data = getImageData(scaleCanvas(canvas, width, height));
				const strData = genBitmapImage(data);
				// use new parameter: fileType
				saveFile(makeURI(strData, downloadMime), fileType, fileName);
			} else {
				const strData = getDataURL(canvas, type, width, height);
				// use new parameter: fileType
				saveFile(strData.replace(type, downloadMime), fileType, fileName);
			}
		}
	};

	const convertToImage = function (canvas, width, height, type) {
		if ($support.canvas && $support.dataURL) {
			if (typeof canvas == "string") {
				canvas = document.getElementById(canvas);
			}
			if (type === undefined) {
				type = "png";
			}
			type = fixType(type);

			if (/bmp/.test(type)) {
				const data = getImageData(scaleCanvas(canvas, width, height));
				const strData = genBitmapImage(data);
				return genImage(makeURI(strData, "image/bmp"));
			} else {
				const strData = getDataURL(canvas, type, width, height);
				return genImage(strData);
			}
		}
	};

	return {
		saveAsImage: saveAsImage,
		saveAsPNG: function (canvas, width, height, fileName) {
			return saveAsImage(canvas, width, height, "png", fileName);
		},
		saveAsJPEG: function (canvas, width, height, fileName) {
			return saveAsImage(canvas, width, height, "jpeg", fileName);
		},
		saveAsGIF: function (canvas, width, height, fileName) {
			return saveAsImage(canvas, width, height, "gif", fileName);
		},
		saveAsBMP: function (canvas, width, height, fileName) {
			return saveAsImage(canvas, width, height, "bmp", fileName);
		},

		convertToImage: convertToImage,
		convertToPNG: function (canvas, width, height) {
			return convertToImage(canvas, width, height, "png");
		},
		convertToJPEG: function (canvas, width, height) {
			return convertToImage(canvas, width, height, "jpeg");
		},
		convertToGIF: function (canvas, width, height) {
			return convertToImage(canvas, width, height, "gif");
		},
		convertToBMP: function (canvas, width, height) {
			return convertToImage(canvas, width, height, "bmp");
		},
	};
})();

// Export function, used in npm
export default Canvas2Image;

全部代码如下

<template>
	<div id="cesiumContainer" style="height: 100vh;"></div>
	<div id="toolbar" style="position: fixed;top:20px;left:220px;">
		<el-breadcrumb>
			<el-breadcrumb-item>场景设置实例</el-breadcrumb-item>
			<el-breadcrumb-item>场景出图</el-breadcrumb-item>
		</el-breadcrumb>
		<el-row class="mb-4" style="margin-top: 15px">
			<el-button type="primary" @click="downSceneImg">图片</el-button>
			<el-button type="primary" @click="downScenePdf">pdf</el-button>
		</el-row>
	</div>
</template>
<script>
import * as Cesium from "cesium";
import InitCesiumHide from "../js/InitCesiumHide.js";
import canvas2image from '../js/canvas2image.js';
import JsPDF from 'jspdf';

export default {
	name: 'cesium24002',
	data() {
		return {
			viewer: undefined,
			scene: undefined
		}
	},
	mounted() {
		let initCesium = new InitCesiumHide('cesiumContainer')
		this.viewer = initCesium.initViewer({
			//cesium状态下允许canvas转图片convertToImage
			contextOptions: {
				webgl: {
					alpha: true,
					depth: false,
					stencil: true,
					antialias: true,
					premultipliedAlpha: true,
					preserveDrawingBuffer: true,
					failIfMajorPerformanceCaveat: true
				},
				allowTextureFilterAnisotropic: true
			}

		});
		//去除版权信息
		this.viewer._cesiumWidget._creditContainer.style.display = "none";
		this.scene = this.viewer.scene;
		this.flyToRight2();
	},
	methods: {
		flyToRight2() {
			let camera = this.viewer.scene.camera;
			camera.flyTo({
				destination: Cesium.Cartesian3.fromDegrees(115.2766, 36.5522, 803.34),
				/*complete: function () {
					setTimeout(function () {
						camera.flyTo({
							destination: Cesium.Cartesian3.fromDegrees(115.2766, 36.5522, 356.50838555841779),
							orientation: {
								heading: Cesium.Math.toRadians(150.0),
								pitch: Cesium.Math.toRadians(-30.0)
							},
							easingFunction: Cesium.EasingFunction.LINEAR_NONE
						});
					}, 1000);
				}*/
			});
		},
		downSceneImg() {
			let canvas = this.viewer.scene.canvas;
			let imageWidth = 1000;
			let img = canvas2image.convertToImage(canvas, imageWidth, imageWidth * canvas.height / canvas.width, 'png');
			let loadImg = document.createElement('a')
			loadImg.href = img.src
			loadImg.download = 'scene'
			loadImg.click()
		},
		downScenePdf() {
			let canvas = this.viewer.scene.canvas;
			let imageWidth = 1000;
			let imageHeight = imageWidth * canvas.height / canvas.width;
			let img = canvas2image.convertToImage(canvas, imageWidth, imageHeight, 'png');
			let PDF = new JsPDF('', 'pt', 'a4');
			PDF.addImage(img, 'png', 0, 0, imageWidth, imageHeight);
			PDF.save('scene.pdf')
		}
		/*,
		downSceneImg() {
			this.viewer.render();
			this.viewer.canvas.toDataURL("image/png");
			let canvas = this.viewer.scene.canvas;
			//只需要定义图片的宽度(高度计算得到)
			let imageWidth = 500;

			//保存(下载)图片
			Canvas2image.saveAsImage(canvas, imageWidth, imageWidth * canvas.height / canvas.width, 'png');

			//转换图片
			let genimg = Canvas2image.convertToImage(canvas, imageWidth, imageWidth * canvas.height / canvas.width, 'png');
			let image = document.getElementById('image');
			image.src = genimg.src;
		}*/
	}
}
</script>
<style>
.el-breadcrumb__inner {
	color: #ffffff !important;
}
</style>

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1426172.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

elementUI中分开的时间日期选择组件,控制日期的禁用

<el-date-picker v-model"query.startTime" type"datetime" :picker-options"startPickerOptions" format"yyyy-MM-dd HH时" popper-class"date-picker" placeholder"选择日期时间"></el-date-picker>…

【Mysql】数据库架构学习合集

目录 1. Mysql整体架构1-1. 连接层1-2. 服务层1-3. 存储引擎层1-4. 文件系统层 2. 一条sql语句的执行过程2-1. 数据库连接池的作用2-2. 查询sql的执行过程2-1. 写sql的执行过程 1. Mysql整体架构 客户端&#xff1a; 由各种语言编写的程序&#xff0c;负责与Mysql服务端进行网…

[C#][opencvsharp]opencvsharp sift和surf特征点匹配

SIFT特征和SURF特征比较 SIFT特征基本介绍 SIFT(Scale-Invariant Feature Transform)特征检测关键特征&#xff1a; 建立尺度空间&#xff0c;寻找极值关键点定位&#xff08;寻找关键点准确位置与删除弱边缘&#xff09;关键点方向指定关键点描述子 建立尺度空间&#xff0…

python爬虫实战——获取酷我音乐数据

嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 开发环境: 版 本&#xff1a; python 3.8 编辑器&#xff1a;pycharm 2022.3.2 模块使用: requests >>> pip install requests 如何安装python第三方模块: win R 输入 cmd 点击确定, 输入安装命令 pip install…

【数据分享】1929-2023年全球站点的逐日最低气温数据(Shp\Excel\免费获取)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2023年全球气象站…

【云原生之kubernetes系列】--污点与容忍

污点与容忍 污点&#xff08;taints)&#xff1a;用于node节点排斥Pod调度&#xff0c;与亲和效果相反&#xff0c;即taint的node排斥Pod的创建容忍&#xff08;toleration)&#xff1a;用于Pod容忍Node节点的污点信息&#xff0c;即node节点有污点&#xff0c;也将新的pod创建…

GM8775C——DSI 转双通道 LVDS 发送器

1 产品概述 GM8775C 型 DSI 转双通道 LVDS 发送器产品主要实现将 MIPI DSI 转单 / 双通道 LVDS 功能&#xff0c; MIPI 支持 1/2/3/4 通道可选&#xff0c;每通道最高支持 1Gbps 速率&#xff0c;最大支持 4Gbps 速率。 LVDS 时钟频率高达 154MHz &#xff…

数据解构+算法(第07篇):动态编程!黄袍加身!

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

【数据分享】1929-2023年全球站点的逐月最高气温数据(Shp\Excel\无需转发)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2023年全球气象站…

vue如何使用vuedraggable实现不同面板之间的拖拽排序,拖拽复制功能?【vuedraggable】

vuedraggable官方文档链接使用说明https://www.itxst.com/vue-draggable/re7vfyfe.htmlhttps://www.itxst.com/vue-draggable/re7vfyfe.html 效果图&#xff1a; 使用vuedraggable拖动左边的字段和逻辑到右边形成不同的规则校验 <!-- ****--date 2024-02-01 11:34****-…

私募证券基金动态-23年12月报

成交量&#xff1a;12月日均7,696.93亿元 2023年12月A股两市日均成交7,696.93亿元&#xff0c;环比下降12.39%、同比下降2.26%。12月整体21个交易日&#xff0c;无单日交易日成交金额过万亿&#xff0c;单日交易日最低成交金额为6,122.84亿元&#xff08;12月25日&#xff09;…

GPT-4 Vision调试任何应用,即使缺少文本日志 升级Streamlit七

GPT-4 Vision 系列: 翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式一翻译: GPT-4 with Vision 升级 Streamlit 应用程序的 7 种方式二翻译: GPT-4 Vision静态图表转换为动态数据可视化 升级Streamlit 三翻译: GPT-4 Vision从图像转换为完全可编辑的表格 升级St…

【C/Python】GtkApplicationWindow

一、C语言 GtkApplicationWindow 是 GTK 库中用于创建应用程序主窗口的一个控件。 首先&#xff0c;需要确保环境安装了GTK开发库。然后&#xff0c;以下是一个简单的使用 GtkApplicationWindow 创建一个 GTK 应用程序的示例&#xff1a; #include <gtk/gtk.h>static …

前端JavaScript篇之let、const、var的区别

目录 let、const、var的区别 let、const、var的区别 let、const和var是JavaScript中用于声明变量的关键字&#xff0c;它们之间有一些区别。 首先&#xff0c;var是在ES5中引入的关键字&#xff0c;而let和const是在ES6中引入的。在ES6之前&#xff0c;我们只能使用var来声明…

Thinkphp5.0.23远程代码执行漏洞复现

★★免责声明★★ 文章中涉及的程序(方法)可能带有攻击性&#xff0c;仅供安全研究与学习之用&#xff0c;读者将信息做其他用途&#xff0c;由Ta承担全部法律及连带责任&#xff0c;文章作者不承担任何法律及连带责任。 1、漏洞介绍 使用Thinkphp5.x远程代码执行漏洞&#xf…

操作系统--进程、线程基础知识

一、进程 我们编写的代码只是一个存储在硬盘的静态文件&#xff0c;通过编译后就会生成二进制可执行文件&#xff0c;当我们运行这个可执行文件后&#xff0c;它会被装载到内存中&#xff0c;接着 CPU 会执行程序中的每一条指令&#xff0c;那么这个运行中的程序&#xff0c;就…

python爬虫-多线程-数据库——WB用户

数据库database的包&#xff1a; Python操作Mysql数据库-CSDN博客 效果&#xff1a; 控制台输出&#xff1a; 数据库记录&#xff1a; 全部代码&#xff1a; import json import os import threading import tracebackimport requests import urllib.request from utils im…

博客文章质量分数列表【分页、排序、搜索】

文章目录 一、分析二、代码1、前端代码2、后端代码 三、实现效果四、总结1、出现安全验证2、401 Unauthorized: [no body] 一、分析 官方提供的质量分查询入口&#xff1a;CSDN质量分 输入我们要查的文章即可&#xff0c;比如&#xff1a;https://blog.csdn.net/qq_36433289/a…

开发板——X210开发板的SD卡启动方式

以下内容源于朱有鹏嵌入式课程的学习与整理&#xff0c;如有侵权请告知删除。 参考博客&#xff1a; S5PV210 SD卡启动 - 简书 关于存储器的相关基础知识&#xff0c;见博文&#xff1a; 外存——SD卡/iNand芯片与S5PV210的SD/MMC/iNand控制器-CSDN博客 RAM、ROM和FLASH三…

了解WPF控件:TreeView常用属性与用法(十五)

引言 TreeView控件是WPF&#xff08;Windows Presentation Foundation&#xff09;中用于显示分层数据的常用控件。这个控件允许用户以树形结构展示数据&#xff0c;使得数据更加清晰易懂。在创建文件浏览器、组织结构图等应用程序时&#xff0c;TreeView控件非常有用。 Tree…