mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
[js] using OffscreenCanvas when DOM is not available (#19033)
### Description
when DOM API is not avaiable, using OffscreenCanvas
### Motivation and Context
In some environment like service worker or web worker, the DOM API is
not avaiable, we can use OffscreenCanvas API to replace
`document.createElement('canvas')`.
Most of the APIs of OffscreenCanvas and HTMLCanvasElement are the same,
except that `toDataUrl` is missing.
It fix this issues #19032
This commit is contained in:
parent
4a5f13b681
commit
a503561d0c
2 changed files with 37 additions and 12 deletions
|
|
@ -8,10 +8,11 @@ import {Tensor} from './tensor.js';
|
|||
* implementation of Tensor.toDataURL()
|
||||
*/
|
||||
export const tensorToDataURL = (tensor: Tensor, options?: TensorToDataUrlOptions): string => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = typeof document !== 'undefined' ? document.createElement('canvas') : (new OffscreenCanvas(1, 1));
|
||||
canvas.width = tensor.dims[3];
|
||||
canvas.height = tensor.dims[2];
|
||||
const pixels2DContext = canvas.getContext('2d');
|
||||
const pixels2DContext =
|
||||
canvas.getContext('2d') as (CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null);
|
||||
|
||||
if (pixels2DContext != null) {
|
||||
// Default values for height and width & format
|
||||
|
|
@ -88,7 +89,11 @@ export const tensorToDataURL = (tensor: Tensor, options?: TensorToDataUrlOptions
|
|||
pixels2DContext.fillRect(j, i, 1, 1);
|
||||
}
|
||||
}
|
||||
return canvas.toDataURL();
|
||||
if ('toDataURL' in canvas) {
|
||||
return canvas.toDataURL();
|
||||
} else {
|
||||
throw new Error('toDataURL is not supported');
|
||||
}
|
||||
} else {
|
||||
throw new Error('Can not access image data');
|
||||
}
|
||||
|
|
@ -98,7 +103,9 @@ export const tensorToDataURL = (tensor: Tensor, options?: TensorToDataUrlOptions
|
|||
* implementation of Tensor.toImageData()
|
||||
*/
|
||||
export const tensorToImageData = (tensor: Tensor, options?: TensorToImageDataOptions): ImageData => {
|
||||
const pixels2DContext = document.createElement('canvas').getContext('2d');
|
||||
const pixels2DContext = typeof document !== 'undefined' ?
|
||||
document.createElement('canvas').getContext('2d') :
|
||||
new OffscreenCanvas(1, 1).getContext('2d') as OffscreenCanvasRenderingContext2D;
|
||||
let image: ImageData;
|
||||
if (pixels2DContext != null) {
|
||||
// Default values for height and width & format
|
||||
|
|
|
|||
|
|
@ -110,13 +110,31 @@ export const tensorFromImage = async(
|
|||
let data: Uint8ClampedArray|undefined;
|
||||
let bufferToTensorOptions: BufferToTensorOptions = options ?? {};
|
||||
|
||||
const createCanvas = () => {
|
||||
if (typeof document !== 'undefined') {
|
||||
return document.createElement('canvas');
|
||||
} else if (typeof OffscreenCanvas !== 'undefined') {
|
||||
return new OffscreenCanvas(1, 1);
|
||||
} else {
|
||||
throw new Error('Canvas is not supported');
|
||||
}
|
||||
};
|
||||
const createCanvasContext = (canvas: HTMLCanvasElement|OffscreenCanvas) => {
|
||||
if (canvas instanceof HTMLCanvasElement) {
|
||||
return canvas.getContext('2d');
|
||||
} else if (canvas instanceof OffscreenCanvas) {
|
||||
return canvas.getContext('2d') as OffscreenCanvasRenderingContext2D;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
// filling and checking image configuration options
|
||||
if (isHTMLImageEle) {
|
||||
// HTMLImageElement - image object - format is RGBA by default
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = createCanvas();
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
const pixels2DContext = canvas.getContext('2d');
|
||||
const pixels2DContext = createCanvasContext(canvas);
|
||||
|
||||
if (pixels2DContext != null) {
|
||||
let height = image.height;
|
||||
|
|
@ -166,12 +184,12 @@ export const tensorFromImage = async(
|
|||
bufferToTensorOptions.width = width;
|
||||
|
||||
if (options !== undefined) {
|
||||
const tempCanvas = document.createElement('canvas');
|
||||
const tempCanvas = createCanvas();
|
||||
|
||||
tempCanvas.width = width;
|
||||
tempCanvas.height = height;
|
||||
|
||||
const pixels2DContext = tempCanvas.getContext('2d');
|
||||
const pixels2DContext = createCanvasContext(tempCanvas);
|
||||
|
||||
if (pixels2DContext != null) {
|
||||
pixels2DContext.putImageData(image, 0, 0);
|
||||
|
|
@ -188,10 +206,10 @@ export const tensorFromImage = async(
|
|||
throw new Error('Please provide image config with format for Imagebitmap');
|
||||
}
|
||||
|
||||
const canvas = document.createElement('canvas');
|
||||
const canvas = createCanvas();
|
||||
canvas.width = image.width;
|
||||
canvas.height = image.height;
|
||||
const pixels2DContext = canvas.getContext('2d');
|
||||
const pixels2DContext = createCanvasContext(canvas);
|
||||
|
||||
if (pixels2DContext != null) {
|
||||
const height = image.height;
|
||||
|
|
@ -206,8 +224,8 @@ export const tensorFromImage = async(
|
|||
}
|
||||
} else if (isString) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const canvas = document.createElement('canvas');
|
||||
const context = canvas.getContext('2d');
|
||||
const canvas = createCanvas();
|
||||
const context = createCanvasContext(canvas);
|
||||
if (!image || !context) {
|
||||
return reject();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue