From 0507bb4dc6418edc64cbe14a42babca9a50ef597 Mon Sep 17 00:00:00 2001 From: Arindam Bose Date: Fri, 20 Dec 2019 17:32:05 -0800 Subject: [PATCH 1/2] Account for ImageBitmap in addImage and updateImage --- src/ui/map.js | 22 +++++++++++----------- src/util/ajax.js | 4 ++-- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ui/map.js b/src/ui/map.js index cd94a280762..0ab91e5a90e 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -4,7 +4,7 @@ import {version} from '../../package.json'; import {extend, bindAll, warnOnce, uniqueId} from '../util/util'; import browser from '../util/browser'; import window from '../util/window'; -const {HTMLImageElement, HTMLElement} = window; +const {HTMLImageElement, HTMLElement, ImageBitmap} = window; import DOM from '../util/dom'; import {getImage, getJSON, ResourceType} from '../util/ajax'; import {RequestManager} from '../util/mapbox'; @@ -1411,7 +1411,7 @@ class Map extends Camera { * A {@link Map#error} event will be fired if there is not enough space in the sprite to add this image. * * @param id The ID of the image. - * @param image The image as an `HTMLImageElement`, `ImageData`, or object with `width`, `height`, and `data` + * @param image The image as an `HTMLImageElement`, `ImageData`, `ImageBitmap` or object with `width`, `height`, and `data` * properties with the same format as `ImageData`. * @param options * @param options.pixelRatio The ratio of pixels in the image to physical pixels on the screen @@ -1447,17 +1447,17 @@ class Map extends Camera { * @see Use `ImageData`: [Add a generated icon to the map](https://www.mapbox.com/mapbox-gl-js/example/add-image-generated/) */ addImage(id: string, - image: HTMLImageElement | ImageData | {width: number, height: number, data: Uint8Array | Uint8ClampedArray} | StyleImageInterface, + image: HTMLImageElement | ImageBitmap | ImageData | {width: number, height: number, data: Uint8Array | Uint8ClampedArray} | StyleImageInterface, {pixelRatio = 1, sdf = false, stretchX, stretchY, content}: $Shape = {}) { this._lazyInitEmptyStyle(); const version = 0; - if (image instanceof HTMLImageElement) { + if (image instanceof HTMLImageElement || (ImageBitmap && image instanceof ImageBitmap)) { const {width, height, data} = browser.getImageData(image); this.style.addImage(id, {data: new RGBAImage({width, height}, data), pixelRatio, stretchX, stretchY, content, sdf, version}); } else if (image.width === undefined || image.height === undefined) { return this.fire(new ErrorEvent(new Error( - 'Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, ' + + 'Invalid arguments to map.addImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, ' + 'or object with `width`, `height`, and `data` properties with the same format as `ImageData`'))); } else { const {width, height, data} = image; @@ -1489,7 +1489,7 @@ class Map extends Camera { * or [`line-pattern`](https://docs.mapbox.com/mapbox-gl-js/style-spec/#paint-line-line-pattern). * * @param id The ID of the image. - * @param image The image as an `HTMLImageElement`, `ImageData`, or object with `width`, `height`, and `data` + * @param image The image as an `HTMLImageElement`, `ImageData`, `ImageBitmap` or object with `width`, `height`, and `data` * properties with the same format as `ImageData`. * * @example @@ -1498,20 +1498,20 @@ class Map extends Camera { * if (map.hasImage('cat')) map.updateImage('cat', './other-cat-icon.png'); */ updateImage(id: string, - image: HTMLImageElement | ImageData | {width: number, height: number, data: Uint8Array | Uint8ClampedArray} | StyleImageInterface) { + image: HTMLImageElement | ImageBitmap | ImageData | {width: number, height: number, data: Uint8Array | Uint8ClampedArray} | StyleImageInterface) { const existingImage = this.style.getImage(id); if (!existingImage) { return this.fire(new ErrorEvent(new Error( 'The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.'))); } - - const imageData = image instanceof HTMLImageElement ? browser.getImageData(image) : image; + const needsDecode = image instanceof HTMLImageElement || (ImageBitmap && image instanceof ImageBitmap); + const imageData = needsDecode ? browser.getImageData(image) : image; const {width, height, data} = imageData; if (width === undefined || height === undefined) { return this.fire(new ErrorEvent(new Error( - 'Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, ' + + 'Invalid arguments to map.updateImage(). The second argument must be an `HTMLImageElement`, `ImageData`, `ImageBitmap`, ' + 'or object with `width`, `height`, and `data` properties with the same format as `ImageData`'))); } @@ -1520,7 +1520,7 @@ class Map extends Camera { 'The width and height of the updated image must be that same as the previous version of the image'))); } - const copy = !(image instanceof HTMLImageElement); + const copy = !needsDecode; existingImage.data.replace(data, copy); this.style.updateImage(id, existingImage); diff --git a/src/util/ajax.js b/src/util/ajax.js index 3c1d26f4d16..be730d0ed93 100644 --- a/src/util/ajax.js +++ b/src/util/ajax.js @@ -276,8 +276,8 @@ function arrayBufferToImageBitmap(data: ArrayBuffer, callback: (err: ?Error, ima const blob: Blob = new window.Blob([new Uint8Array(data)], {type: 'image/png'}); window.createImageBitmap(blob).then((imgBitmap) => { callback(null, imgBitmap); - }).catch(() => { - callback(new Error('Could not load image. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.')); + }).catch((e) => { + callback(new Error(`Could not load image because of ${e.message}. Please make sure to use a supported image type such as PNG or JPEG. Note that SVGs are not supported.`)); }); } From c4bb1f099c509849beaf0bea03b5eebfb4d5d0e9 Mon Sep 17 00:00:00 2001 From: Arindam Bose Date: Fri, 20 Dec 2019 17:48:15 -0800 Subject: [PATCH 2/2] Fix flow errors --- src/ui/map.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/ui/map.js b/src/ui/map.js index 0ab91e5a90e..09fcec02512 100755 --- a/src/ui/map.js +++ b/src/ui/map.js @@ -1505,8 +1505,7 @@ class Map extends Camera { return this.fire(new ErrorEvent(new Error( 'The map has no image with that id. If you are adding a new image use `map.addImage(...)` instead.'))); } - const needsDecode = image instanceof HTMLImageElement || (ImageBitmap && image instanceof ImageBitmap); - const imageData = needsDecode ? browser.getImageData(image) : image; + const imageData = (image instanceof HTMLImageElement || (ImageBitmap && image instanceof ImageBitmap)) ? browser.getImageData(image) : image; const {width, height, data} = imageData; if (width === undefined || height === undefined) { @@ -1520,7 +1519,7 @@ class Map extends Camera { 'The width and height of the updated image must be that same as the previous version of the image'))); } - const copy = !needsDecode; + const copy = !(image instanceof HTMLImageElement || (ImageBitmap && image instanceof ImageBitmap)); existingImage.data.replace(data, copy); this.style.updateImage(id, existingImage);