@loaders.gl/images
Version:
Framework-independent loaders and writers for images (PNG, JPG, ...)
72 lines (61 loc) • 2.04 kB
text/typescript
import type {ImageLoaderOptions} from '../../image-loader';
import {isSVG, getBlob} from './svg-utils';
import {parseToImage} from './parse-to-image';
const EMPTY_OBJECT = {};
let imagebitmapOptionsSupported = true;
/**
* Asynchronously parses an array buffer into an ImageBitmap - this contains the decoded data
* ImageBitmaps are supported on worker threads, but not supported on Edge, IE11 and Safari
* https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap#Browser_compatibility
*
* TODO - createImageBitmap supports source rect (5 param overload), pass through?
*/
export async function parseToImageBitmap(
arrayBuffer: ArrayBuffer,
options: ImageLoaderOptions,
url?: string
): Promise<ImageBitmap> {
let blob;
// Cannot parse SVG directly to ImageBitmap, parse to Image first
if (isSVG(url)) {
// Note: this only works on main thread
const image = await parseToImage(arrayBuffer, options, url);
blob = image;
} else {
// Create blob from the array buffer
blob = getBlob(arrayBuffer, url);
}
const imagebitmapOptions = options && options.imagebitmap;
return await safeCreateImageBitmap(blob, imagebitmapOptions);
}
/**
* Safely creates an imageBitmap with options
* *
* Firefox crashes if imagebitmapOptions is supplied
* Avoid supplying if not provided or supported, remember if not supported
*/
async function safeCreateImageBitmap(
blob: Blob,
imagebitmapOptions: ImageBitmapOptions | null = null
): Promise<ImageBitmap> {
if (isEmptyObject(imagebitmapOptions) || !imagebitmapOptionsSupported) {
imagebitmapOptions = null;
}
if (imagebitmapOptions) {
try {
// @ts-ignore Options
return await createImageBitmap(blob, imagebitmapOptions);
} catch (error) {
console.warn(error); // eslint-disable-line
imagebitmapOptionsSupported = false;
}
}
return await createImageBitmap(blob);
}
function isEmptyObject(object) {
// @ts-ignore
for (const key in object || EMPTY_OBJECT) {
return false;
}
return true;
}