Skip to content

Commit

Permalink
feat(pixel): update .blitCanvas(), .toImageData()
Browse files Browse the repository at this point in the history
BREAKING CHANGE: add BlitCanvasOpts for optional .blitCanvas() args

- update .blitCanvas() impls
- update .toImageData() impls to accept pre-existing ImageData instance
- add ensureImageData() check
  • Loading branch information
postspectacular committed Sep 27, 2022
1 parent 4656c50 commit 85e4e38
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 15 deletions.
24 changes: 21 additions & 3 deletions packages/pixel/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,16 +238,15 @@ export interface IBlit<T extends IPixelBuffer> {
*/
blitCanvas(
canvas: HTMLCanvasElement | CanvasRenderingContext2D,
x?: number,
y?: number
opts?: Partial<BlitCanvasOpts>
): void;
}

export interface IToImageData {
/**
* Returns the contents of the pixel buffer as HTML canvas `ImageData`.
*/
toImageData(): ImageData;
toImageData(idata?: ImageData): ImageData;
}

export interface IBlend<T extends IPixelBuffer, F> {
Expand Down Expand Up @@ -328,6 +327,25 @@ export interface BlitOpts {
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 PoolTemplate = Fn3<string[], number, number, string>;

export interface ConvolutionKernelSpec {
Expand Down
14 changes: 14 additions & 0 deletions packages/pixel/src/checks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ export const ensureSize = (
stride = 1
) => assert(data.length >= width * height * stride, "pixel buffer too small");

/** @internal */
export const ensureImageData = (
data: ImageData | undefined,
width: number,
height: number
) =>
data
? (assert(
data.width === width && data.height === height,
"imagedata has wrong dimensions"
),
data)
: new ImageData(width, height);

/** @internal */
export const ensureChannel = (fmt: IntFormat | FloatFormat, id: number) => {
const chan = fmt.channels[id];
Expand Down
12 changes: 6 additions & 6 deletions packages/pixel/src/float.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { clamp01 } from "@thi.ng/math/interval";
import { postmultiply, premultiply } from "@thi.ng/porter-duff/premultiply";
import type {
BlendFnFloat,
BlitCanvasOpts,
BlitOpts,
Filter,
FloatFormat,
Expand All @@ -21,7 +22,7 @@ import type {
IResizable,
IToImageData,
} from "./api.js";
import { ensureChannel, ensureSize } from "./checks.js";
import { ensureChannel, ensureImageData, ensureSize } from "./checks.js";
import { defFloatFormat } from "./format/float-format.js";
import { FLOAT_GRAY } from "./format/float-gray.js";
import { FLOAT_RGBA } from "./index.js";
Expand Down Expand Up @@ -320,18 +321,17 @@ export class FloatBuffer

blitCanvas(
canvas: HTMLCanvasElement | CanvasRenderingContext2D,
x = 0,
y = 0
opts: Partial<BlitCanvasOpts> = {}
) {
const ctx =
canvas instanceof HTMLCanvasElement
? canvas.getContext("2d")!
: canvas;
ctx.putImageData(this.toImageData(), x, y);
ctx.putImageData(this.toImageData(opts.data), opts.x || 0, opts.y || 0);
}

toImageData() {
const idata = new ImageData(this.width, this.height);
toImageData(idata?: ImageData) {
idata = ensureImageData(idata, this.width, this.height);
const dest = new Uint32Array(idata.data.buffer);
const {
stride: [stride],
Expand Down
17 changes: 11 additions & 6 deletions packages/pixel/src/int.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
} from "@thi.ng/porter-duff/premultiply";
import {
BlendFnInt,
BlitCanvasOpts,
BlitOpts,
Filter,
IBlend,
Expand All @@ -26,7 +27,12 @@ import {
Lane,
} from "./api.js";
import { canvasPixels, imageCanvas } from "./canvas.js";
import { ensureAlpha, ensureChannel, ensureSize } from "./checks.js";
import {
ensureAlpha,
ensureChannel,
ensureImageData,
ensureSize,
} from "./checks.js";
import { ABGR8888 } from "./format/abgr8888.js";
import { defIntFormat } from "./format/int-format.js";
import {
Expand Down Expand Up @@ -277,18 +283,17 @@ export class IntBuffer

blitCanvas(
canvas: HTMLCanvasElement | CanvasRenderingContext2D,
x = 0,
y = 0
opts: Partial<BlitCanvasOpts> = {}
) {
const ctx =
canvas instanceof HTMLCanvasElement
? canvas.getContext("2d")!
: canvas;
ctx.putImageData(this.toImageData(), x, y);
ctx.putImageData(this.toImageData(opts.data), opts.x || 0, opts.y || 0);
}

toImageData() {
const idata = new ImageData(this.width, this.height);
toImageData(idata?: ImageData) {
idata = ensureImageData(idata, this.width, this.height);
const dest = new Uint32Array(idata.data.buffer);
const src = this.data;
const fmt = this.format.toABGR;
Expand Down

0 comments on commit 85e4e38

Please sign in to comment.