UNPKG

@awayjs/stage

Version:
153 lines (124 loc) 4.21 kB
import { BitmapImage2D } from '../image/BitmapImage2D'; import { BitmapImageCube } from '../image/BitmapImageCube'; import { Image2D } from '../image/Image2D'; import { ImageSampler } from '../image/ImageSampler'; import { IImageFactory } from '../factories/IImageFactory'; import { ImageCube } from '../image'; export class ImageUtils { private static CANVAS: HTMLCanvasElement; private static CONTEXT: CanvasRenderingContext2D; public static MAX_SIZE: number = 8192; private static _defaultImage2DFactory: () => Image2D; private static _defaultImageCubeFactory: () => ImageCube; private static _defaultImageSamplerFactory: () => ImageSampler; private static _defaultFactory: () => IImageFactory; private static _defaultImageSampler: ImageSampler; private static _defaultImage2D: Image2D; private static _defaultImageCube: ImageCube; private static getImageBuffer(img: HTMLImageElement | ImageBitmap): Uint8ClampedArray { const canvas = this.CANVAS || (this.CANVAS = document.createElement('canvas')); const context = this.CONTEXT || (this.CONTEXT = canvas.getContext('2d', { willReadFrequently: true })); if (img instanceof HTMLImageElement) { canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; } else { canvas.width = img.width; canvas.height = img.height; } context.drawImage(img, 0, 0); return context.getImageData(0, 0, canvas.width, canvas.height).data; } /** * */ public static imageToBitmapImage2D( img: HTMLImageElement | ImageBitmap, factory: IImageFactory, powerOfTwo: boolean = true): BitmapImage2D { let width: number; let height: number; if (img instanceof HTMLImageElement) { width = img.naturalWidth; height = img.naturalHeight; } else { width = img.width; height = img.height; } const image2D = <BitmapImage2D> factory.createImage2D( width, height, true, null, powerOfTwo ); image2D.addLazySymbol({ needParse: true, definition: { width, height, isPMA: true, data: null }, lazyParser() { this.needParse = false; this.definition.data = ImageUtils.getImageBuffer(img); this.lazyParser = null; return this; } }); return image2D; } public static isImage2DValid(image2D: Image2D): boolean { if (image2D == null) return true; return this.isDimensionValid(image2D.width, image2D.powerOfTwo) && this.isDimensionValid(image2D.height, image2D.powerOfTwo); } public static isHTMLImageElementValid(image: HTMLImageElement): boolean { if (image == null) return true; return this.isDimensionValid(image.width) && this.isDimensionValid(image.height); } public static isDimensionValid(d: number, powerOfTwo: boolean = true): boolean { return d >= 1 && d <= this.MAX_SIZE && (!powerOfTwo || this.isPowerOfTwo(d)); } public static isPowerOfTwo(value: number): boolean { return value ? ((value & -value) == value) : false; } public static getBestPowerOf2(value: number): number { let p: number = 1; while (p < value) p <<= 1; if (p > this.MAX_SIZE) p = this.MAX_SIZE; return p; } public static getDefaultImage2D(): Image2D { return this._defaultImage2D || (this._defaultImage2D = this._defaultImage2DFactory()); } public static getDefaultImageCube(): ImageCube { return this._defaultImageCube || (this._defaultImageCube = this._defaultImageCubeFactory()); } public static getDefaultImageSampler(): ImageSampler { return this._defaultImageSampler || (this._defaultImageSampler = this._defaultImageSamplerFactory()); } public static registerDefaults ( defaultImage2DFactory: () => BitmapImage2D = null, defaultImageCubeFactory: () => BitmapImageCube = null, defaultImageSamplerFactory: () => ImageSampler = null, defaultFactory: () => IImageFactory = null ) { if (defaultImage2DFactory) { this._defaultImage2DFactory = defaultImage2DFactory; } if (defaultImageCubeFactory) { this._defaultImageCubeFactory = defaultImageCubeFactory; } if (defaultImageSamplerFactory) { this._defaultImageSamplerFactory = defaultImageSamplerFactory; } if (defaultFactory) { this._defaultFactory = defaultFactory; } } } export default ImageUtils;