cesium把当前的场景截图,下载图片或pdf
安装
npm install canvas2image --savenpm 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>