Skip to content

Commit 46956a0

Browse files
video-layer 优化拉伸效果
1 parent 6322a74 commit 46956a0

File tree

2 files changed

+79
-7
lines changed

2 files changed

+79
-7
lines changed

src/common/overlay/video/VideoLayerRenderer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class VideoLayerRenderer {
2929
video.id = this.layerId;
3030
video.className = 'video-js';
3131
video.style.position = 'fixed';
32-
video.style.left = '-200%';
32+
video.style.left = '-300%';
3333
video.setAttribute('crossorigin', 'anonymous');
3434
document.body.appendChild(video);
3535
}

src/mapboxgl/overlay/VideoLayer.js

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@
44
import mapboxgl from 'mapbox-gl';
55
import { Util as CommonUtil } from '@supermap/iclient-common/commontypes/Util';
66
import { VideoLayerRenderer } from '@supermap/iclient-common/overlay/video/VideoLayerRenderer';
7+
import { bbox, polygon } from '@turf/turf';
78

89
/**
910
* @class VideoLayer
1011
* @category Visualization Video
1112
* @modulecategory Overlay
1213
* @param {Object} options - 构造参数。
13-
* @param {string} [options.id] - 专题图层 ID。默认使用 CommonUtil.createUniqueID("VideoLayer_") 创建专题图层 ID
14-
* @param {string} [options.url] - 视频 或 流链接。支持 flv, m3u8 流格式
15-
* @param {string} [options.extent] - 视频范围
14+
* @param {string} options.url - 视频 或 流链接。支持 flv, m3u8 流格式
15+
* @param {Array} options.extent - 视频范围
16+
* @param {string} [options.id] - 视频图层 ID。默认使用 CommonUtil.createUniqueID("VideoLayer_") 创建专题图层 ID
1617
* @extends {mapboxgl.Evented}
1718
* @usage
1819
*/
@@ -24,8 +25,12 @@ export class VideoLayer extends mapboxgl.Evented {
2425
this.options = _options;
2526
this.url = this.options.url;
2627
this.extent = this.options.extent;
28+
this.cv = this.options.opencv || window.cv;
29+
if (!this.cv) {
30+
throw new Error('opencv.js is not existed!');
31+
}
2732
this.id = _options.id ? _options.id : CommonUtil.createUniqueID("VideoLayer_");
28-
this.layerId = this.id + 'outer';
33+
this.layerId = this.id + '_outer';
2934
this.type = 'custom';
3035
this.renderingMode = '3d';
3136
this.overlay = true;
@@ -44,7 +49,11 @@ export class VideoLayer extends mapboxgl.Evented {
4449
this.video.play();
4550
});
4651
this.video.one('ready', () => {
52+
setTimeout(() => {
53+
this.videoWidth = this.video.videoWidth();
54+
this.videoHeight = this.video.videoHeight();
4755
this._addVideoLayer(this.map);
56+
}, 1000);
4857
});
4958
this.video.one('canplay', () => {
5059
setTimeout(() => {
@@ -53,14 +62,77 @@ export class VideoLayer extends mapboxgl.Evented {
5362
});
5463
}
5564

56-
render() { }
65+
render() {}
66+
67+
getPixelBbox(map) {
68+
let res = [];
69+
let minX = 0;
70+
let minY = 0;
71+
this.extent.forEach((item) => {
72+
let result = map.project(item);
73+
if (!minX || result.x < minX) {
74+
minX = result.x;
75+
}
76+
if (!minY || result.y < minY) {
77+
minY = result.y;
78+
}
79+
res.push(result.x);
80+
res.push(result.y);
81+
});
82+
res = res.map((item, index) => {
83+
if (index % 2 === 0) {
84+
return item - minX;
85+
} else {
86+
return item - minY;
87+
}
88+
});
89+
return res;
90+
}
5791

5892
_addVideoLayer(map) {
5993
let url = this.videoDomId || this.url;
94+
this.pixelBBox = this.getPixelBbox(map);
95+
const result = bbox(polygon([
96+
this.extent.concat(this.extent[0])
97+
]));
98+
let br = map.project([result[2], result[3]]);
99+
let tl = map.project([result[0], result[1]]);
100+
let size = [Math.abs(br.x - tl.x), Math.abs(br.y - tl.y)];
101+
let ratio = size[0] / size[1];
102+
let realX = this.videoHeight * ratio;
103+
let realY = this.videoHeight;
104+
let ratioX = realX / size[0];
105+
let ratioY = realY / size[1];
106+
this.pixelBBox = this.pixelBBox.map((item, index) => {
107+
if (index % 2 === 0) {
108+
return item * ratioX;
109+
} else {
110+
return item * ratioY;
111+
}
112+
});
113+
this.dsize = new this.cv.Size(this.videoHeight * ratio, this.videoHeight);
114+
let that = this;
115+
let srcTri = this.cv.matFromArray(4, 1, this.cv.CV_32FC2, [0, 0, that.videoWidth, 0, that.videoWidth, that.videoHeight, 0, that.videoHeight]);
116+
let dstTri = this.cv.matFromArray(4, 1, this.cv.CV_32FC2, this.pixelBBox);
60117
map.addSource(this.layerId, {
61118
type: 'video',
62119
urls: [url],
63-
coordinates: this.extent
120+
drawImageCallback(frame) {
121+
let src = that.cv.matFromImageData(frame);
122+
let dst = new that.cv.Mat();
123+
let M = that.cv.findHomography(srcTri, dstTri);
124+
that.cv.warpPerspective(src, dst, M, that.dsize);
125+
let newFrame = new ImageData(new Uint8ClampedArray(dst.data), dst.cols, dst.rows);
126+
src.delete();
127+
dst.delete();
128+
return newFrame;
129+
},
130+
coordinates: [
131+
[result[0], result[3]],
132+
[result[2], result[3]],
133+
[result[2], result[1]],
134+
[result[0], result[1]]
135+
]
64136
});
65137

66138
map.addLayer(

0 commit comments

Comments
 (0)