You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
4.6 KiB
128 lines
4.6 KiB
|
|
function imageDataFromCanvas(image : CanvasImageSource, width : number, height : number) : ImageData {
|
|
const canvas = document.createElement("canvas");
|
|
const canvasCtx = canvas.getContext("2d");
|
|
|
|
canvas.width = width;
|
|
canvas.height = height;
|
|
|
|
canvasCtx.drawImage(image, 0, 0, width, height);
|
|
|
|
return canvasCtx.getImageData(0, 0, width, height);
|
|
}
|
|
|
|
async function imageDataFromBlob(blob : Blob) : Promise<ImageData> {
|
|
// turn blob into an img element and pass back to imageDataFrom
|
|
const url = URL.createObjectURL(blob)
|
|
|
|
const image = new Image()
|
|
image.src = url
|
|
|
|
await new Promise((resolve, reject) => {
|
|
image.onload = resolve
|
|
image.onerror = reject
|
|
})
|
|
|
|
URL.revokeObjectURL(url)
|
|
|
|
return imageDataFrom(image)
|
|
}
|
|
|
|
export async function imageDataFrom(image : ImageBitmapSource) : Promise<ImageData> {
|
|
// spec quoted from:
|
|
// https://wicg.github.io/shape-detection-api/#image-sources-for-detection
|
|
|
|
// [TODO]
|
|
// If any ImageBitmapSource have an effective script origin (origin) which is
|
|
// not the same as the Document’s effective script origin, then reject the
|
|
// Promise with a new DOMException whose name is SecurityError.
|
|
|
|
if (image instanceof HTMLImageElement) {
|
|
|
|
// [TODO]
|
|
// When an ImageBitmapSource object represents an HTMLImageElement, the
|
|
// element’s image must be used as the source image. Specifically, when an
|
|
// ImageBitmapSource object represents an animated image in an
|
|
// HTMLImageElement, the user agent must use the default image of the
|
|
// animation (the one that the format defines is to be used when animation
|
|
// is not supported or is disabled), or, if there is no such image, the
|
|
// first frame of the animation.
|
|
|
|
// [SPEC]
|
|
// If the ImageBitmapSource is an HTMLImageElement object that is in the
|
|
// Broken (HTML Standard §img-error) state, then reject the Promise with a
|
|
// new DOMException whose name is InvalidStateError, and abort any further
|
|
// steps.
|
|
// [SPEC]
|
|
// If the ImageBitmapSource is an HTMLImageElement object that is not fully
|
|
// decodable then reject the Promise with a new DOMException whose name is
|
|
// InvalidStateError, and abort any further steps
|
|
try {
|
|
image.decode()
|
|
} catch (_) {
|
|
throw new DOMException("HTMLImageElement is not decodable", "InvalidStateError")
|
|
}
|
|
|
|
return imageDataFromCanvas(image, image.naturalWidth, image.naturalHeight)
|
|
|
|
} else if (image instanceof SVGImageElement) {
|
|
|
|
// TODO width/height is a little bit arbitrary
|
|
return imageDataFromCanvas(image, 640, 480)
|
|
|
|
} else if (image instanceof HTMLVideoElement) {
|
|
|
|
// [SPEC]
|
|
// If the ImageBitmapSource is an HTMLVideoElement object whose readyState
|
|
// attribute is either HAVE_NOTHING or HAVE_METADATA then reject the Promise
|
|
// with a new DOMException whose name is InvalidStateError, and abort any
|
|
// further steps.
|
|
const HAVE_NOTHING = 0, HAVE_METADATA = 1;
|
|
if (image.readyState === HAVE_NOTHING || image.readyState === HAVE_METADATA) {
|
|
throw new DOMException("", "InvalidStateError")
|
|
}
|
|
|
|
// [SPEC]
|
|
// When an ImageBitmapSource object represents an HTMLVideoElement, then
|
|
// the frame at the current playback position when the method with the
|
|
// argument is invoked must be used as the source image when processing the
|
|
// image, and the source image’s dimensions must be the intrinsic dimensions
|
|
// of the media resource (i.e. after any aspect-ratio correction has been applied).
|
|
return imageDataFromCanvas(image, image.videoWidth, image.videoHeight)
|
|
|
|
} else if (image instanceof HTMLCanvasElement) {
|
|
|
|
// [TODO]
|
|
// When an ImageBitmapSource object represents an HTMLCanvasElement, the
|
|
// element’s bitmap must be used as the source image.
|
|
|
|
// [TODO]
|
|
// If the ImageBitmapSource argument is an HTMLCanvasElement whose bitmap’s
|
|
// origin-clean (HTML Standard §concept-canvas-origin-clean) flag is false,
|
|
// then reject the Promise with a new DOMException whose name is
|
|
// SecurityError, and abort any further steps.
|
|
|
|
const canvasCtx = image.getContext("2d")
|
|
return canvasCtx.getImageData(0, 0, image.width, image.height)
|
|
|
|
} else if (image instanceof ImageBitmap) {
|
|
|
|
return imageDataFromCanvas(image, image.width, image.height)
|
|
|
|
} else if (image instanceof OffscreenCanvas) {
|
|
|
|
const canvasCtx = image.getContext("2d")
|
|
return canvasCtx.getImageData(0, 0, image.width, image.height)
|
|
|
|
} else if (image instanceof Blob) {
|
|
|
|
return imageDataFromBlob(image)
|
|
|
|
} else if (image instanceof ImageData) {
|
|
|
|
return image
|
|
|
|
} else {
|
|
// TODO TypeError?
|
|
}
|
|
}
|