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

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>
相关推荐
活宝小娜4 小时前
vue不刷新浏览器更新页面的方法
前端·javascript·vue.js
程序视点4 小时前
【Vue3新工具】Pinia.js:提升开发效率,更轻量、更高效的状态管理方案!
前端·javascript·vue.js·typescript·vue·ecmascript
coldriversnow4 小时前
在Vue中,vue document.onkeydown 无效
前端·javascript·vue.js
刚刚好ā5 小时前
js作用域超全介绍--全局作用域、局部作用、块级作用域
前端·javascript·vue.js·vue
会发光的猪。7 小时前
css使用弹性盒,让每个子元素平均等分父元素的4/1大小
前端·javascript·vue.js
天下代码客7 小时前
【vue】vue中.sync修饰符如何使用--详细代码对比
前端·javascript·vue.js
周全全8 小时前
Spring Boot + Vue 基于 RSA 的用户身份认证加密机制实现
java·vue.js·spring boot·安全·php
ZwaterZ8 小时前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
码农六六8 小时前
vue3封装Element Plus table表格组件
javascript·vue.js·elementui
徐同保8 小时前
el-table 多选改成单选
javascript·vue.js·elementui