From e8cd2968e059a1038693058428626c836e64b281 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Mon, 30 Nov 2020 14:02:08 -0500 Subject: [PATCH 1/7] Multiresolution support --- .../components/annotators/ImageAnnotator.vue | 41 ++++++++++++------- client/src/components/annotators/annotator.js | 24 +++++++++++ 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/client/src/components/annotators/ImageAnnotator.vue b/client/src/components/annotators/ImageAnnotator.vue index 3bc8f702c..809852db4 100644 --- a/client/src/components/annotators/ImageAnnotator.vue +++ b/client/src/components/annotators/ImageAnnotator.vue @@ -81,7 +81,12 @@ export default Vue.extend({ this.frame = frame; this.syncedFrame = frame; this.emitFrame(); - this.cacheImages(); + const imgs = await this.cacheImages(); + // reset dimensions of map from new image + const img = await imgs[this.frame]; + this.width = img.naturalWidth; + this.height = img.naturalHeight; + this.resetMapDimensions(); this.quadFeature .data([ { @@ -153,7 +158,7 @@ export default Vue.extend({ await this.loadFrame(frame); } // Cache a new range of images based on current frame - this.cacheNewRange(min, max); + return this.cacheNewRange(min, max); }, /** * Wraps loading of a single frame in a promise, used to gurantee frame loads @@ -181,40 +186,48 @@ export default Vue.extend({ * @param {int} max upper bound frame number for caching */ cacheNewRange(min, max) { + const frameImages = []; for (let i = this.frame; i <= max; i += 1) { - this.cacheFrame(i); + frameImages[i] = this.cacheFrame(i); const minusFrame = this.frame - (i - this.frame); if (minusFrame >= min) { this.cacheFrame(minusFrame); } } + return frameImages; }, /** * Adds a single frame to the pendingImgs array for loading and assigns it to the master * imgs list. Once the image is loaded it is removed from the pendingImgs * @param {int} i the image to cache if it isn't already assigned + * @returns {Array>>} loaded images */ cacheFrame(i) { + let p = Promise.resolve(this.imgs[i]); if (!this.imgs[i]) { const img = new Image(); img.crossOrigin = 'Anonymous'; this.imgs[i] = img; const imageAndFrame = [img, i]; this.pendingImgs.add(imageAndFrame); - img.onload = () => { - this.pendingImgs.delete(imageAndFrame); - img.onload = null; - img.cached = true; - // If we are trying to play and waiting for loaded frames we check the cache again - if (this.playing && this.loadingVideo) { - if (this.checkCached(this.playCache)) { - this.loadingVideo = false; - this.syncWithVideo(); + p = new Promise((resolve) => { + img.onload = () => { + this.pendingImgs.delete(imageAndFrame); + img.onload = null; + img.cached = true; + // If we are trying to play and waiting for loaded frames we check the cache again + if (this.playing && this.loadingVideo) { + if (this.checkCached(this.playCache)) { + this.loadingVideo = false; + this.syncWithVideo(); + } } - } - }; + resolve(img); + }; + }); this.loadImageFunc(this.imageData[i], img); } + return p; }, /** * Checks to see if there is enough cached images to play for X seconds diff --git a/client/src/components/annotators/annotator.js b/client/src/components/annotators/annotator.js index cba312f7a..c7215634a 100644 --- a/client/src/components/annotators/annotator.js +++ b/client/src/components/annotators/annotator.js @@ -72,6 +72,28 @@ export default { setImageCursor(newCursor) { this.imageCursor = `${newCursor}`; }, + resetMapDimensions() { + this.geoViewer.bounds({ + left: 0, + top: 0, + bottom: this.height, + right: this.width, + }); + const params = geo.util.pixelCoordinateParams( + this.$refs.container, + this.width, + this.height, + this.width, + this.height, + ); + this.geoViewer.maxBounds({ + left: 0, + top: 0, + right: params.map.maxBounds.right, + bottom: params.map.maxBounds.bottom, + }); + this.geoViewer.zoomRange(params.map); + }, baseInit() { const params = geo.util.pixelCoordinateParams( this.$refs.container, @@ -81,6 +103,7 @@ export default { this.height, ); this.geoViewer = geo.map(params.map); + this.setMapRange(); this.geoViewer.zoomRange({ min: this.geoViewer.zoomRange().origMin, max: this.geoViewer.zoomRange().max + 3, @@ -117,6 +140,7 @@ export default { interactorOpts.wheelScaleY = 0.2; this.geoViewer.interactor().options(interactorOpts); }, + prevFrame() { const targetFrame = this.frame - 1; if (targetFrame >= 0) { From 485a33025f49c3240b99b509cc3747e53382e673 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Mon, 30 Nov 2020 15:27:14 -0500 Subject: [PATCH 2/7] change ref --- client/src/components/annotators/annotator.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/annotators/annotator.js b/client/src/components/annotators/annotator.js index c7215634a..b88e35648 100644 --- a/client/src/components/annotators/annotator.js +++ b/client/src/components/annotators/annotator.js @@ -103,7 +103,7 @@ export default { this.height, ); this.geoViewer = geo.map(params.map); - this.setMapRange(); + this.resetMapDimensions(); this.geoViewer.zoomRange({ min: this.geoViewer.zoomRange().origMin, max: this.geoViewer.zoomRange().max + 3, From 455b0c0556004c952bdeba7ffb5a095adb9ada47 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Wed, 2 Dec 2020 12:37:33 -0500 Subject: [PATCH 3/7] Respond to comments --- .../components/annotators/ImageAnnotator.vue | 59 +++++++++++-------- client/src/components/annotators/annotator.js | 2 + 2 files changed, 35 insertions(+), 26 deletions(-) diff --git a/client/src/components/annotators/ImageAnnotator.vue b/client/src/components/annotators/ImageAnnotator.vue index 809852db4..c267eb6f7 100644 --- a/client/src/components/annotators/ImageAnnotator.vue +++ b/client/src/components/annotators/ImageAnnotator.vue @@ -54,19 +54,10 @@ export default Vue.extend({ this.quadFeatureLayer = this.geoViewer.createLayer('feature', { features: ['quad'], }); - this.quadFeature = this.quadFeatureLayer - .createFeature('quad') - .data([ - { - ul: { x: 0, y: 0 }, - lr: { x: this.width, y: this.height }, - image: this.imgs[this.frame], - }, - ]) - .draw(); + this.quadFeature = this.quadFeatureLayer.createFeature('quad'); + this.drawImage(this.imgs[this.frame]); this.ready = true; }, - async play() { try { this.playing = true; @@ -75,29 +66,43 @@ export default Vue.extend({ console.error(ex); } }, - - async seek(frame) { - this.lastFrame = this.frame; - this.frame = frame; - this.syncedFrame = frame; - this.emitFrame(); - const imgs = await this.cacheImages(); - // reset dimensions of map from new image - const img = await imgs[this.frame]; - this.width = img.naturalWidth; - this.height = img.naturalHeight; - this.resetMapDimensions(); + drawImage(img) { + if ((img.naturalWidth !== this.width) || (img.naturalHeight !== this.height)) { + this.width = img.naturalWidth; + this.height = img.naturalHeight; + this.resetMapDimensions(); + } this.quadFeature .data([ { ul: { x: 0, y: 0 }, lr: { x: this.width, y: this.height }, - image: this.imgs[frame], + image: img, }, ]) .draw(); }, - + async seek(newFrame) { + this.lastFrame = this.frame; + this.frame = newFrame; + this.syncedFrame = newFrame; + this.emitFrame(); + const imgsPromise = this.cacheImages(); + const img = this.imgs[newFrame]; + if (img.cached) { + // if image is already loaded, draw it now + this.drawImage(img); + } else { + // else wait for it to load + const imgs = await imgsPromise; + const loadedImg = await imgs[newFrame]; + if (loadedImg !== undefined && loadedImg.frame === this.frame) { + // if the image exists () + // and the seek hasn't changed since the image completed loading, draw it. + this.drawImage(loadedImg); + } + } + }, pause() { this.playing = false; this.loadingVideo = false; @@ -174,6 +179,7 @@ export default Vue.extend({ img.onload = () => { img.onload = null; img.cached = true; + img.frame = frame; resolve(frame); }; this.loadImageFunc(this.imageData[frame], img); @@ -211,10 +217,11 @@ export default Vue.extend({ const imageAndFrame = [img, i]; this.pendingImgs.add(imageAndFrame); p = new Promise((resolve) => { - img.onload = () => { + img.onload = (evt) => { this.pendingImgs.delete(imageAndFrame); img.onload = null; img.cached = true; + img.frame = i; // If we are trying to play and waiting for loaded frames we check the cache again if (this.playing && this.loadingVideo) { if (this.checkCached(this.playCache)) { diff --git a/client/src/components/annotators/annotator.js b/client/src/components/annotators/annotator.js index b88e35648..6c5a3e1f4 100644 --- a/client/src/components/annotators/annotator.js +++ b/client/src/components/annotators/annotator.js @@ -93,6 +93,8 @@ export default { bottom: params.map.maxBounds.bottom, }); this.geoViewer.zoomRange(params.map); + this.geoViewer.zoom(this.geoViewer.zoomRange().origMin); + this.geoViewer.center({ x: 0, y: 0 }); }, baseInit() { const params = geo.util.pixelCoordinateParams( From 7654609ad4f13128b853d7c5884e0b26e84221fa Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Mon, 30 Nov 2020 14:02:08 -0500 Subject: [PATCH 4/7] Multiresolution support --- client/src/components/annotators/ImageAnnotator.vue | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/client/src/components/annotators/ImageAnnotator.vue b/client/src/components/annotators/ImageAnnotator.vue index c267eb6f7..4013f75fb 100644 --- a/client/src/components/annotators/ImageAnnotator.vue +++ b/client/src/components/annotators/ImageAnnotator.vue @@ -217,11 +217,18 @@ export default Vue.extend({ const imageAndFrame = [img, i]; this.pendingImgs.add(imageAndFrame); p = new Promise((resolve) => { +<<<<<<< HEAD img.onload = (evt) => { this.pendingImgs.delete(imageAndFrame); img.onload = null; img.cached = true; img.frame = i; +======= + img.onload = () => { + this.pendingImgs.delete(imageAndFrame); + img.onload = null; + img.cached = true; +>>>>>>> a9841e4... Multiresolution support // If we are trying to play and waiting for loaded frames we check the cache again if (this.playing && this.loadingVideo) { if (this.checkCached(this.playCache)) { From 105ca51b8f6d0fd04c54d561e4c433c5edb577eb Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Wed, 2 Dec 2020 12:43:58 -0500 Subject: [PATCH 5/7] Failed again --- client/src/components/annotators/ImageAnnotator.vue | 7 ------- 1 file changed, 7 deletions(-) diff --git a/client/src/components/annotators/ImageAnnotator.vue b/client/src/components/annotators/ImageAnnotator.vue index 4013f75fb..c267eb6f7 100644 --- a/client/src/components/annotators/ImageAnnotator.vue +++ b/client/src/components/annotators/ImageAnnotator.vue @@ -217,18 +217,11 @@ export default Vue.extend({ const imageAndFrame = [img, i]; this.pendingImgs.add(imageAndFrame); p = new Promise((resolve) => { -<<<<<<< HEAD img.onload = (evt) => { this.pendingImgs.delete(imageAndFrame); img.onload = null; img.cached = true; img.frame = i; -======= - img.onload = () => { - this.pendingImgs.delete(imageAndFrame); - img.onload = null; - img.cached = true; ->>>>>>> a9841e4... Multiresolution support // If we are trying to play and waiting for loaded frames we check the cache again if (this.playing && this.loadingVideo) { if (this.checkCached(this.playCache)) { From 1cf607afae35a8f5551f1eef5ee3384b07e45f9f Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Wed, 2 Dec 2020 14:14:50 -0500 Subject: [PATCH 6/7] Update client/src/components/annotators/ImageAnnotator.vue Co-authored-by: BryonLewis <61746913+BryonLewis@users.noreply.github.com> --- client/src/components/annotators/ImageAnnotator.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/annotators/ImageAnnotator.vue b/client/src/components/annotators/ImageAnnotator.vue index c267eb6f7..c9f499d53 100644 --- a/client/src/components/annotators/ImageAnnotator.vue +++ b/client/src/components/annotators/ImageAnnotator.vue @@ -217,7 +217,7 @@ export default Vue.extend({ const imageAndFrame = [img, i]; this.pendingImgs.add(imageAndFrame); p = new Promise((resolve) => { - img.onload = (evt) => { + img.onload = () => { this.pendingImgs.delete(imageAndFrame); img.onload = null; img.cached = true; From a93f63ecaededd1c2a1dac7d01f161f61b869b41 Mon Sep 17 00:00:00 2001 From: Brandon Davis Date: Wed, 2 Dec 2020 14:15:00 -0500 Subject: [PATCH 7/7] Update client/src/components/annotators/ImageAnnotator.vue Co-authored-by: BryonLewis <61746913+BryonLewis@users.noreply.github.com> --- client/src/components/annotators/ImageAnnotator.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/components/annotators/ImageAnnotator.vue b/client/src/components/annotators/ImageAnnotator.vue index c9f499d53..c6bb9394d 100644 --- a/client/src/components/annotators/ImageAnnotator.vue +++ b/client/src/components/annotators/ImageAnnotator.vue @@ -206,7 +206,7 @@ export default Vue.extend({ * Adds a single frame to the pendingImgs array for loading and assigns it to the master * imgs list. Once the image is loaded it is removed from the pendingImgs * @param {int} i the image to cache if it isn't already assigned - * @returns {Array>>} loaded images + * @returns {Array>>} loaded images */ cacheFrame(i) { let p = Promise.resolve(this.imgs[i]);