效果
注意图中只保持 canvas 图,不包含时钟轴等信息,如右上角所示。
关键代码
代码第 2 行,必须调方法 render 。
// 更新和渲染三维场景。必须加上,否则无法获取场景图片
viewer.scene.render();
// 将场景 canvas 转为 png
let pngImg = Cesium.ReImg.fromCanvas(viewer.canvas).toPng();
// 将 png 转为 File 对象
let fileObj = this.pngToFile(pngImg);
// 创建序列化表单数据
let formData = new FormData();
formData.append("file", fileObj);
// 头设置
let config = { headers: { 'Content-Type': 'multipart/form-data' } };
// 上传图片地址
let url = 'http://localhot:8080/files/fs/upload'
// 调接口
axios.post(encodeURI(url), formData, config).then(response =>{
if([200, 201].includes(response.status)) {
this.imgId = response.data.obj;
}
}).catch(err => {
console.error(err);
this.$message.error('上传失败')
})
png 转为 File 对象方法,代码第 7 行使用 Window atob,解码使用 base-64 编码的字符串。
// png 转为 File 对象
pngToFile(img){
// 注意这里是 img 对象,使用 src 属性
let arr = img.src.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
// 解码使用 base-64 编码的字符串
let bytes = window.atob(arr[1]);
let n = bytes.length;
let ia = new Uint8Array(n);
while (n--) {
ia[n] = bytes.charCodeAt(n);
}
// 创建 File 对象
return new File([ia], 'freeze.png', { type: mime });
}
完整代码
<template>
<div id="index">
<div id="cesiumContainer"></div>
<div style="position:absolute;top:0;right:0;z-index:10;">
<button @click="onClick">上传图片</button><br/>
<img :src="imgUrl + imgId" alt="" @click="turnTo(item)">
</div>
</div>
</template>
<script>
import axios from 'axios'
let viewer;
export default {
data () {
return {
imgUrl: `http://localhot:8080/files/fs/preview?fileId=`,
imgId: ''
}
},
methods: {
init() {
// viewer = new Cesium.Viewer('cesiumContainer');
viewer = new Cesium.Viewer('cesiumContainer', {
terrainExaggeration: 1,
infoBox: true,
animation: true,
timeline: true
});
},
onClick() {
// 更新和渲染三维场景。必须加上,否则无法获取场景图片
viewer.scene.render();
// 将场景 canvas 转为 png
let pngImg = Cesium.ReImg.fromCanvas(viewer.canvas).toPng();
// 将 png 转为 File 对象
let fileObj = this.pngToFile(pngImg);
// 创建序列化表单数据
let formData = new FormData();
formData.append("file", fileObj);
// param.append("cesium_img", 'mason');
// 头设置
let config = { headers: { 'Content-Type': 'multipart/form-data' } };
// 上传图片地址
let url = 'http://localhot:8080/files/fs/upload'
// 调接口
axios.post(encodeURI(url), formData, config).then(response =>{
if([200, 201].includes(response.status)) {
this.imgId = response.data.obj;
}
}).catch(err => {
console.error(err);
this.$message.error('上传失败')
})
},
// png 转为 File 对象
pngToFile(img){
// 注意这里是 img 对象,使用 src 属性
let arr = img.src.split(',');
let mime = arr[0].match(/:(.*?);/)[1];
// 解码使用 base-64 编码的字符串
let bytes = window.atob(arr[1]);
let n = bytes.length;
let ia = new Uint8Array(n);
while (n--) {
ia[n] = bytes.charCodeAt(n);
}
// 创建 File 对象
return new File([ia], 'freeze.png', { type: mime });
}
},
mounted() {
this.$nextTick(() => {
this.init()
});
}
}
</script>
<style>
* {
padding: 0;
margin: 0;
}
#index, #cesiumContainer {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
}
img {
width: 300px;
height: 150px;
border: 3px solid #ff0;
}
</style>