Skip to content

Commit

Permalink
feat(text-canvas): add ImageOpts, update image(), add resize(), extra…
Browse files Browse the repository at this point in the history
…ct()
  • Loading branch information
postspectacular committed Feb 22, 2020
1 parent d88bf9d commit 73f941a
Show file tree
Hide file tree
Showing 2 changed files with 76 additions and 5 deletions.
30 changes: 29 additions & 1 deletion packages/text-canvas/src/api.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Fn } from "@thi.ng/api";
import { Fn, NumOrString } from "@thi.ng/api";

export const enum Align {
LEFT,
Expand Down Expand Up @@ -31,6 +31,34 @@ export interface TextBoxOpts {
style: StrokeStyle;
}

export interface ImageOpts {
/**
* Target characters in order of increasing brightness. If chars are
* given as number, `format` option will NOT be applied, but is
* assumed to be already encoded in the number.
*
* @defaultValue {@link SHADES}
*/
chars: NumOrString[];
/**
* Format to apply to all chars.
*/
format: number;
/**
* Gamma correction value / exponent. All source pixel values will
* be raised by this exponent.
*
* @defaultValue 2.2
*/
gamma: number;
/**
* Number of bits/pixel in source image (only grayscale supported)
*
* @defaultValue 8
*/
bits: number;
}

export interface ClipRect {
x1: number;
y1: number;
Expand Down
51 changes: 47 additions & 4 deletions packages/text-canvas/src/image.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { peek } from "@thi.ng/arrays";
import { SHADES } from "./api";
import { ImageOpts, SHADES } from "./api";
import { Canvas } from "./canvas";
import { charCode, intersectRect } from "./utils";

Expand All @@ -22,15 +22,49 @@ export const blit = (canvas: Canvas, x: number, y: number, src: Canvas) => {
}
};

export const resize = (canvas: Canvas, newWidth: number, newHeight: number) => {
if (canvas.width === newWidth && canvas.height === newHeight) return;
const dest = new Canvas(newWidth, newHeight);
dest.buf.fill(charCode(0x20, canvas.format));
blit(dest, 0, 0, canvas);
canvas.buf = dest.buf;
canvas.width = newWidth;
canvas.height = newHeight;
canvas.clipRects = [
{ x1: 0, y1: 0, x2: newWidth, y2: newHeight, w: newWidth, h: newHeight }
];
};

export const extract = (
canvas: Canvas,
x: number,
y: number,
w: number,
h: number
) => {
const dest = new Canvas(w, h, canvas.format, peek(canvas.styles));
blit(dest, -x, -y, canvas);
return dest;
};

/**
*
* @param canvas
* @param x
* @param y
* @param w
* @param h
* @param pixels
* @param opts
*/
export const image = (
canvas: Canvas,
x: number,
y: number,
w: number,
h: number,
pixels: ArrayLike<number>,
format = canvas.format,
gamma = 2.2
opts?: Partial<ImageOpts>
) => {
x |= 0;
y |= 0;
Expand All @@ -44,12 +78,21 @@ export const image = (
if (!iw || !ih) return;
const sx = Math.max(0, x1 - x);
const sy = Math.max(0, y1 - y);
const { chars, format, gamma, bits } = {
chars: SHADES,
format: canvas.format,
gamma: 2.2,
bits: 8,
...opts
};
const norm = 1 / ((1 << bits) - 1);
const num = chars.length - 1;
for (let yy = sy, dy = y1; dy < y2; yy++, dy++) {
let sidx = sx + yy * w;
let didx = x1 + dy * width;
for (let xx = sx, dx = x1; dx < x2; xx++, dx++) {
buf[didx++] = charCode(
SHADES[(Math.pow(pixels[sidx++] / 255, gamma) * 4) | 0],
chars[(Math.pow(pixels[sidx++] * norm, gamma) * num + 0.5) | 0],
format
);
}
Expand Down

0 comments on commit 73f941a

Please sign in to comment.