@thi.ng/pixel
Version:
Typedarray integer & float pixel buffers w/ customizable formats, blitting, drawing, convolution
377 lines • 10.2 kB
TypeScript
import type { Fn, Fn2, FnU2, IGrid2D, IObjectOf, Maybe, NumericArray, Range0_3, TypedArray, UintType } from "@thi.ng/api";
import type { CanvasContext, OffscreenCanvasContext } from "@thi.ng/canvas";
/**
* ABGR 8bit lane/channel IDs
*/
export declare enum Lane {
ALPHA = 0,
BLUE = 1,
GREEN = 2,
RED = 3
}
/**
* Wrap behaviors (currently unused)
*/
export type Wrap = "clamp" | "wrap" | "repeat";
/**
* Filtered access types (currently unused)
*/
export type Filter = "nearest" | "linear" | "cubic";
/**
* Blend function (for packed integers) given to IBlend implementations.
*/
export type BlendFnInt = Fn2<number, number, number>;
export type BlendFnFloat = (out: NumericArray | null, src: NumericArray, dest: NumericArray) => NumericArray;
/**
* Color channel getter. Returns 0-based channel value (regardless of shift/bit
* position)
*/
export type ChannelGetter<T> = Fn<T, number>;
/**
* Color channel setter. Takes current full pixel value and 0-based channel
* value to set (regardless of shift/bit position). Returns updated pixel value.
*/
export type ChannelSetter<T> = Fn2<T, number, T>;
export interface IABGRConvert<T> {
/**
* Converts given ABGR value into internal pixel format.
*/
fromABGR: (x: number, out?: T) => T;
/**
* Converts given internal pixel format value to packed ABGR.
*/
toABGR: Fn<T, number>;
}
export interface IntChannelSpec {
/**
* Channel size in bits (1-8)
*/
size: number;
/**
* Related ABGR lane this channel is mapped from/to. Only used if parent
* format uses auto-generated {@link IABGRConvert} implementation (i.e. only
* if no-user defined converters are given to {@link IntFormatSpec}).
*/
lane?: Lane;
}
export interface IntChannel {
/**
* Channel size in bits (1-8)
*/
size: number;
/**
* Number of possible values in channel (i.e. `1 << size`)
*/
num: number;
/**
* Bit shift offset (in bits, not shifted value)
*/
shift: number;
/**
* Shift from ABGR channel offset
*/
abgrShift: number;
/**
* 0-based channel bit mask (WRT parent format)
*/
mask0: number;
/**
* Aligned bit mask (WRT parent format)
*/
maskA: number;
/**
* Original channel/lane ID in ABGR
*/
lane: Lane;
/**
* Int value accessor
*/
int: ChannelGetter<number>;
/**
* Int value accessor
*/
setInt: ChannelSetter<number>;
/**
* Normalized float accessor
*/
float: ChannelGetter<number>;
/**
* Normalized float accessor
*/
setFloat: ChannelSetter<number>;
}
/**
* Format configuration passed to {@link defIntFormat}.
*/
export interface IntFormatSpec extends Partial<IABGRConvert<number>> {
/**
* Storage / typed array type
*/
type: UintType;
/**
* Number of actual used bits (must be <= `size`)
*/
size: number;
/**
* Number of alpha channel bits. MUST be given if format uses alpha
* channel.
*
* @defaultValue 0
*/
alpha?: number;
/**
* Individual channel configurations
*/
channels: IntChannelSpec[];
}
/**
* Compiled format object returned by {@link defIntFormat}.
*/
export interface IntFormat extends IABGRConvert<number> {
type: UintType;
/**
* Total size in bits.
*/
size: number;
/**
* Number of bits for alpha channel.
*/
alpha: number;
channels: IntChannel[];
readonly __packed: true;
}
export interface FloatFormatSpec {
alpha?: boolean;
gray?: boolean;
channels: Lane[];
/**
* If given, {@link defFloatFormat} won't generate conversions and use those
* provided instead.
*/
convert?: IABGRConvert<NumericArray>;
}
export interface FloatFormat extends IABGRConvert<NumericArray> {
readonly __float: true;
alpha: boolean;
gray: boolean;
/**
* Number of channels
*/
size: number;
shift: IObjectOf<number>;
channels: Lane[];
range: [number, number];
/**
* Maps given value to `[0,1]` interval. Used in combination with
* {@link IntChannel.setFloat}.
*
* @param val
*/
normalized(val: number): number;
fromNormalized(val: number): number;
}
export interface RawPixelBuffer extends CanvasContext {
img: ImageData;
data: Uint32Array<ArrayBuffer>;
}
export interface OffscreenRawPixelBuffer extends OffscreenCanvasContext {
img: ImageData;
data: Uint32Array<ArrayBuffer>;
}
export interface IPixelBuffer<T extends TypedArray = TypedArray, P = any> extends IGrid2D<T, P> {
readonly width: number;
readonly height: number;
/**
* Pixel format.
*
* @remarks
* When modifying this value, it's the user's responsibility to ensure
* storage compatibility between old and new formats. If the number of
* channels or channel resolution varies, use `.as(newFormat)` to trigger an
* actual conversion.
*/
format: IABGRConvert<any>;
/**
* Extracts region as new pixel buffer in same format.
*
* @param x -
* @param y -
* @param width -
* @param height -
*/
getRegion(x: number, y: number, width: number, height: number): Maybe<IPixelBuffer<T, P>>;
}
export interface IBlit<T extends IPixelBuffer> {
/**
* Blits pixels into given `dest` pixel buffer, using provided options. If
* `dest` buffer is smaller than source buffer, only the top-left region
* will be written.
*
* Destination MUST be of same format as original. No conversion is
* performed.
*
* @param dest -
* @param opts -
*/
blit(dest: T, opts?: Partial<BlitOpts>): void;
/**
* Converts and blits pixels into given canvas (or canvas context) at
* position `x`, `y` (0,0 by default). If canvas is smaller than source
* buffer, only the top-left region will be written.
*/
blitCanvas(canvas: HTMLCanvasElement | CanvasRenderingContext2D | OffscreenCanvas | OffscreenCanvasRenderingContext2D, opts?: Partial<BlitCanvasOpts>): void;
}
export interface ISetImageData {
setImageData(idata: ImageData): this;
}
export interface IToImageData {
/**
* Returns the contents of the pixel buffer as HTML canvas `ImageData`.
*/
toImageData(idata?: ImageData): ImageData;
}
export interface IBlend<T extends IPixelBuffer, F> {
/**
* Uses given `op` function to blend / composite pixels of this buffer with
* those of `dest` and writes results into `dest`. Supports same options as
* `blit()`.
*
* @param op -
* @param dest -
* @param opts -
*/
blend(op: F, dest: T, opts?: Partial<BlitOpts>): void;
/**
* Premultiplies alpha of all pixels (requires a pixel format with alpha
* channel).
*
* @remarks
* Usually called before starting a compositing/blending process. See
* {@link IBlend.postmultiply} for reverse operation.
*/
premultiply(): this;
/**
* Postmultiplies alpha of all pixels (requires a pixel format with alpha
* channel).
*
* @remarks
* Usually called after the final compositing/blending step. See
* {@link IBlend.premultiply} for reverse operation.
*/
postmultiply(): this;
/**
* Returns true if all pixels in the buffer are _likely_ to be already using
* pre-multiplied alpha, i.e. if all channel values of a pixel are less than
* or equal to that pixel's alpha value.
*/
isPremultiplied(): boolean;
}
export interface IInvert<T extends IPixelBuffer> {
invert(): T;
}
export interface IResizable<T extends IPixelBuffer, F> {
scale(scale: number, sampler?: F | Filter): T;
resize(w: number, h: number, sampler?: F | Filter): T;
}
export interface IRotate<T extends IPixelBuffer> {
/**
* Rotates pixel buffer according to given ID:
*
* - 0 = no rotation
* - 1 = {@link IRotate.rotateCW}
* - 2 = {@link IRotate.rotate180}
* - 3 = {@link IRotate.rotateCCW}
*
* @param id
*/
rotateByID(id: Range0_3): T;
/**
* Rotates pixel buffer 90 degrees clockwise.
*/
rotateCW(): T;
/**
* Rotates pixel buffer 90 degrees counterclockwise.
*/
rotateCCW(): T;
/**
* Rotates pixel buffer 180 degrees.
*/
rotate180(): T;
}
/** @internal */
export declare const ROT_IDS: Rotation[];
export type Rotation = Exclude<keyof IRotate<IPixelBuffer>, "rotateByID">;
export interface IColorChannel<T extends TypedArray, C> {
/**
* Returns new pixel buffer of selected color channel. The extracted values
* are a copy of the original.
*/
getChannel(id: C): IPixelBuffer<T, number>;
/**
* Replaces selected color channel with values from given pixel buffer,
* which MUST be of same size as target.
*
* @param id -
* @param buf -
*/
setChannel(id: C, buf: IPixelBuffer<T, number> | number): this;
}
export interface BlitOpts {
/**
* Destination X position (top-left)
*
* @defaultValue 0
*/
dx: number;
/**
* Destination Y position (top-left)
*
* @defaultValue 0
*/
dy: number;
/**
* Source X position (top-left)
*
* @defaultValue 0
*/
sx: number;
/**
* Source Y position (top-left)
*
* @defaultValue 0
*/
sy: number;
/**
* Source region width
*
* @defaultValue buffer width
*/
w: number;
/**
* Source region width
*
* @defaultValue buffer height
*/
h: number;
}
export interface BlitCanvasOpts {
/**
* Pre-existing ImageData instance (must be same dimensions as pixel buffer)
*/
data: ImageData;
/**
* Target X coordinate
*
* @defaultValue 0
*/
x: number;
/**
* Target Y coordinate
*
* @defaultValue 0
*/
y: number;
}
export type IntSampler = FnU2<number>;
export type FloatSampler = FnU2<number, NumericArray>;
//# sourceMappingURL=api.d.ts.map