@loaders.gl/images
Version:
Framework-independent loaders and writers for images (PNG, JPG, ...)
55 lines (48 loc) • 1.98 kB
text/typescript
import type {ImageLoaderOptions} from '../../image-loader';
import {getBlobOrSVGDataUrl} from './svg-utils';
// Parses html image from array buffer
export async function parseToImage(
arrayBuffer: ArrayBuffer,
options: ImageLoaderOptions,
url?: string
): Promise<HTMLImageElement> {
// Note: image parsing requires conversion to Blob (for createObjectURL).
// Potentially inefficient for not using `response.blob()` (and for File / Blob inputs)...
// But presumably not worth adding 'blob' flag to loader objects?
const blobOrDataUrl = getBlobOrSVGDataUrl(arrayBuffer, url);
const URL = self.URL || self.webkitURL;
const objectUrl = typeof blobOrDataUrl !== 'string' && URL.createObjectURL(blobOrDataUrl);
try {
return await loadToImage(objectUrl || blobOrDataUrl, options);
} finally {
if (objectUrl) {
URL.revokeObjectURL(objectUrl);
}
}
}
export async function loadToImage(url, options): Promise<HTMLImageElement> {
const image = new Image();
image.src = url;
// The `image.onload()` callback does not guarantee that the image has been decoded
// so a main thread "freeze" can be incurred when using the image for the first time.
// `Image.decode()` returns a promise that completes when image is decoded.
// https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/decode
// Note: When calling `img.decode()`, we do not need to wait for `img.onload()`
// Note: `HTMLImageElement.decode()` is not available in Edge and IE11
if (options.image && options.image.decode && image.decode) {
await image.decode();
return image;
}
// Create a promise that tracks onload/onerror callbacks
return await new Promise((resolve, reject) => {
try {
image.onload = () => resolve(image);
image.onerror = (error) => {
const message = error instanceof Error ? error.message : 'error';
reject(new Error(message));
};
} catch (error) {
reject(error);
}
});
}