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>
相关推荐
Momo__5 小时前
Vue 3.6 Vapor Mode:跳过虚拟 DOM,性能极致优化
前端·vue.js
优化控制仿真模型5 小时前
【2026】新大纲普通话考试真题题库50套(PDF电子版)
经验分享·pdf
walking9576 小时前
重新学习前端之JavaScript
前端·vue.js·面试
walking9576 小时前
重新学习前端之HTML
前端·vue.js·面试
walking9576 小时前
重新学习前端之Vue
前端·vue.js·面试
泉城老铁6 小时前
springboot实现word转换pdf
vue.js·后端
walking9576 小时前
重新学习前端之Linux
前端·vue.js·面试
walking9576 小时前
重新学习前端之CSS
前端·vue.js·面试
walking9576 小时前
重新学习前端之Git
前端·vue.js·面试
Hello--_--World7 小时前
Vue指令:v-if vs v-show、v-if 与 v-for 的优先级冲突、自定义指令
前端·javascript·vue.js