@awayjs/stage
Version:
Stage for AwayJS
153 lines (124 loc) • 4.21 kB
text/typescript
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;