From 5ca7b1d2c30d890698d54c8a2be53749c8b31a37 Mon Sep 17 00:00:00 2001 From: Omar Azmi <64020006+omar-azmi@users.noreply.github.com> Date: Wed, 8 Feb 2023 11:50:30 -0500 Subject: [PATCH] use much faster background canvas composition for generating atlas mask images, instead of `ImageData` manipulation bump version --- deno.json | 2 +- src/deps.ts | 4 ++++ src/jatlas.ts | 36 ++++++++++++++++++------------------ 3 files changed, 23 insertions(+), 19 deletions(-) diff --git a/deno.json b/deno.json index 46034e8..6453d9f 100644 --- a/deno.json +++ b/deno.json @@ -1,6 +1,6 @@ { "name": "jacked_atlas_ts", - "version": "0.1.4", + "version": "0.1.5", "description": "a tool for extracting region of interest based on a bitmap mask", "author": "Omar Azmi", "license": "Lulz plz don't steal yet", diff --git a/src/deps.ts b/src/deps.ts index 94bc85a..2c4f4c2 100644 --- a/src/deps.ts +++ b/src/deps.ts @@ -6,3 +6,7 @@ export { UnitInterval } from "https://deno.land/x/kitchensink_ts@v0.5.7/typedefs export type Ctx2D = CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D +export const rgbaToHex = (rgba: [r: number, g: number, b: number, a: number]) => "#" + rgba.map(x => { + const hex = x.toString(16) + return hex.length === 2 ? hex : "0" + hex +}).join("") diff --git a/src/jatlas.ts b/src/jatlas.ts index 28a2d29..23f239b 100644 --- a/src/jatlas.ts +++ b/src/jatlas.ts @@ -1,4 +1,4 @@ -import { AnyImageSource, Base64ImageString, ImageBlob, Intervals, Rect, SimpleImageData, blobToBase64, constructImageBitmapSource, constructImageBlob, constructImageData, coordinateTransformer, getBGCanvas, getBGCtx, sliceIntervalsTypedSubarray } from "./deps.ts" +import { AnyImageSource, Base64ImageString, ImageBlob, Intervals, Rect, SimpleImageData, blobToBase64, constructImageBitmapSource, constructImageBlob, constructImageData, coordinateTransformer, getBGCanvas, getBGCtx, sliceIntervalsTypedSubarray, rgbaToHex } from "./deps.ts" import { Sprite } from "./sprite.ts" type FilePath = string @@ -387,24 +387,24 @@ export class JAtlasManager { for (const [id, mask] of Object.entries(this.entries)) { queued_drawings.push( mask.loaded - .then(m => constructImageData(m.data!)) - .then(mask_img_data => { + .then(async (m) => { const - { width: w, height: h, data } = mask_img_data, - color = id_coloring_func!(parseFloat(id)) - console.log(color, mask.rect.x, mask.rect.y, w, h) - for (let i = 0, len = data.length; i < len; i += 4) { - if (data[i] + data[i + 1] + data[i + 2] > 0) { - data[i] = color[0] - data[i + 1] = color[1] - data[i + 2] = color[2] - data[i + 3] = color[3] - } else data[i + 3] = 0 - } - return createImageBitmap(mask_img_data) - }) - .then((bitmap) => { - ctx.drawImage(bitmap, mask.rect.x, mask.rect.y) + mask_img_bitmap = await createImageBitmap(m.data!), + { width: w, height: h } = m.rect, + color = rgbaToHex(id_coloring_func!(parseFloat(id))) + bg_canvas.width = w + bg_canvas.height = h + bg_ctx.resetTransform() + bg_ctx.globalCompositeOperation = "copy" + bg_ctx.drawImage(mask_img_bitmap, 0, 0) + bg_ctx.globalCompositeOperation = "source-in" + bg_ctx.fillStyle = color + bg_ctx.fillRect(0, 0, w, h) + ctx.drawImage( + bg_canvas.transferToImageBitmap(), + m.rect.x, + m.rect.y + ) }) ) }