UNPKG

@thi.ng/imago

Version:

JSON & API-based declarative and extensible image processing trees/pipelines

68 lines (67 loc) 1.59 kB
import { typedArray } from "@thi.ng/api"; import { ABGR8888, GRAY8, Lane, intBuffer } from "@thi.ng/pixel"; import { ATKINSON, BURKES, DIFFUSION_2D, DIFFUSION_COLUMN, DIFFUSION_ROW, FLOYD_STEINBERG, JARVIS_JUDICE_NINKE, SIERRA2, STUCKI, defBayer, ditherWith, orderedDither } from "@thi.ng/pixel-dither"; import sharp from "sharp"; const DITHER_KERNELS = { atkinson: ATKINSON, burkes: BURKES, column: DIFFUSION_COLUMN, diffusion: DIFFUSION_2D, floyd: FLOYD_STEINBERG, jarvis: JARVIS_JUDICE_NINKE, row: DIFFUSION_ROW, sierra: SIERRA2, stucki: STUCKI }; const ditherProc = async (spec, input, ctx) => { let { mode, num = 2, rgb = false, size = 8 } = spec; const [w, h] = ctx.size; let raw; if (rgb) { const tmp = await input.clone().ensureAlpha(1).toColorspace("srgb").raw().toBuffer({ resolveWithObject: true }); raw = tmp.data.buffer; rgb = tmp.info.channels === 4; } else { raw = (await input.clone().grayscale().raw().toBuffer()).buffer; } let img = intBuffer( w, h, rgb ? ABGR8888 : GRAY8, typedArray(rgb ? "u32" : "u8", raw) ); if (mode === "bayer") { orderedDither(img, defBayer(size), rgb ? [num, num, num] : [num]); } else { ditherWith(DITHER_KERNELS[mode], img, { channels: rgb ? [Lane.RED, Lane.GREEN, Lane.BLUE] : void 0 }); } if (!rgb) img = img.as(ABGR8888); return [ sharp(new Uint8Array(img.data.buffer), { raw: { width: img.width, height: img.height, channels: 4 } }), true ]; }; export { ditherProc };