From 7015cad13842834cc5ecb5f98a22afefe655c7e6 Mon Sep 17 00:00:00 2001 From: Michael Hadley Date: Fri, 31 Jan 2025 13:20:04 -0600 Subject: [PATCH] Monorepo stack 3: Tidy up (#45) * Rm examples * Fix up API * Changelog --- README.md | 4 + .../node/buch-tileset-extruded-minified.png | Bin 8901 -> 0 bytes examples/node/buch-tileset-extruded.png | Bin 46357 -> 0 bytes examples/node/buch-tileset.png | Bin 41082 -> 0 bytes examples/node/extrude-example.js | 19 - .../node/extrude-with-minification-example.js | 19 - packages/tile-extruder/src/cli.ts | 6 +- packages/tile-extruder/src/copy-pixels.ts | 98 ++++-- packages/tile-extruder/src/index.ts | 333 ++++++++++-------- 9 files changed, 255 insertions(+), 224 deletions(-) delete mode 100644 examples/node/buch-tileset-extruded-minified.png delete mode 100644 examples/node/buch-tileset-extruded.png delete mode 100644 examples/node/buch-tileset.png delete mode 100644 examples/node/extrude-example.js delete mode 100644 examples/node/extrude-with-minification-example.js diff --git a/README.md b/README.md index c1b18de..2c45387 100644 --- a/README.md +++ b/README.md @@ -149,6 +149,10 @@ Tips: ## Changelog +* Next release (unreleased) + * Breaking change to library. `extrudeTilesetToBuffer`, + `extrudeTilesetToImage`, and `extrudeTilesetToJimp` take object arguments + instead of positional arguments. * 2.1.1 * Update all deps to latest. * 2.1.0 diff --git a/examples/node/buch-tileset-extruded-minified.png b/examples/node/buch-tileset-extruded-minified.png deleted file mode 100644 index 378012dd6ae841e21823bd0d7677b1983479b44c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8901 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 ZtUBFSH*%?p^B4T5d{F&Bmi);}{|hlnRfGTl diff --git a/examples/node/buch-tileset.png b/examples/node/buch-tileset.png deleted file mode 100644 index 18dfbdfbe6ca3c3f1fa3be1f56a33417a4bfc1f3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41082 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 diff --git a/examples/node/extrude-example.js b/examples/node/extrude-example.js deleted file mode 100644 index 9d655a4..0000000 --- a/examples/node/extrude-example.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Example showing how to use the asynchronous extrudeTilesetToImage method to save out a new image - * containing an extruded tileset. - */ - -const { extrudeTilesetToImage } = require("../../bin/index"); - -async function main() { - console.log("Starting an extrusion..."); - try { - await extrudeTilesetToImage(16, 16, "./buch-tileset.png", "./buch-tileset-extruded.png"); - } catch (err) { - console.log("Oh no, an error occurred!"); - console.error(err); - } - console.log("Extrusion finished."); -} - -main(); diff --git a/examples/node/extrude-with-minification-example.js b/examples/node/extrude-with-minification-example.js deleted file mode 100644 index 794b7ea..0000000 --- a/examples/node/extrude-with-minification-example.js +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Example showing how to combine image extrusion with image minification via the popular imagemin - * plugin. - */ - -const { extrudeTilesetToBuffer } = require("../../bin/index"); -const imagemin = require("imagemin").default; -const imageminPngquant = require("imagemin-pngquant").default; -const fs = require("fs"); - -async function main() { - const buffer = await extrudeTilesetToBuffer(16, 16, "./buch-tileset.png"); - const minifiedBuffer = await imagemin.buffer(buffer, { - plugins: [imageminPngquant()], - }); - fs.writeFileSync("./buch-tileset-extruded-minified.png", minifiedBuffer); -} - -main(); diff --git a/packages/tile-extruder/src/cli.ts b/packages/tile-extruder/src/cli.ts index cdcdde9..ee9cfe7 100644 --- a/packages/tile-extruder/src/cli.ts +++ b/packages/tile-extruder/src/cli.ts @@ -62,7 +62,11 @@ if (!outputPath) { modifiedOutputPath = `${reducedInputPath}_extruded.${inputFileExtension}`; } -extrudeTilesetToImage(tileWidth, tileHeight, inputPath, modifiedOutputPath, { +extrudeTilesetToImage({ + tileWidth, + tileHeight, + inputPath, + outputPath: modifiedOutputPath, margin, spacing, extrusion, diff --git a/packages/tile-extruder/src/copy-pixels.ts b/packages/tile-extruder/src/copy-pixels.ts index 75f58e3..70a9db1 100644 --- a/packages/tile-extruder/src/copy-pixels.ts +++ b/packages/tile-extruder/src/copy-pixels.ts @@ -1,26 +1,36 @@ import type { JimpInstance } from "jimp"; /** - * This copies the source pixels to the destination without any alpha blending. - * @param {Image} srcImage A Jimp image to copy pixels from. - * @param {number} srcX X position to start copying from (left). - * @param {number} srcY Y position to start copying from (top). - * @param {number} srcW The width of the region to copy. - * @param {number} srcH The height of the region to copy. - * @param {Image} destImage A Jimp image to paste the pixels to. - * @param {number} destX X position to start pasting to (left). - * @param {number} destY Y position to start pasting to (top). + * This copies the source pixels from a rectangular region of a Jimp image to a + * destination rectangle in another Jimp image, without any alpha blending. */ -function copyPixels( - srcImage: JimpInstance, - srcX: number, - srcY: number, - srcW: number, - srcH: number, - destImage: JimpInstance, - destX: number, - destY: number, -) { +function copyPixels({ + srcImage, + srcX, + srcY, + srcW, + srcH, + destImage, + destX, + destY, +}: { + /** A Jimp image to copy pixels from. */ + srcImage: JimpInstance; + /** X position to start copying from (left). */ + srcX: number; + /** Y position to start copying from (top). */ + srcY: number; + /** The width of the region to copy. */ + srcW: number; + /** The height of the region to copy. */ + srcH: number; + /** A Jimp image to paste the pixels to. */ + destImage: JimpInstance; + /** X position to start pasting to (left). */ + destX: number; + /** Y position to start pasting to (top). */ + destY: number; +}) { srcImage.scan(srcX, srcY, srcW, srcH, (curSrcX, curSrcY, curSrcIndex) => { const curDestX = destX + (curSrcX - srcX); const curDestY = destY + (curSrcY - srcY); @@ -33,28 +43,38 @@ function copyPixels( } /** - * This copies the source pixel to every pixel in the destination rectangle without any alpha blending. - * @param {Image} srcImage A Jimp image to copy pixel from. - * @param {number} srcX X position of the source pixel. - * @param {number} srcY Y position of the source pixel. - * @param {Image} destImage A Jimp image to paste the pixel to. - * @param {number} destX X position to start pasting to (left). - * @param {number} destY Y position to start pasting to (top). - * @param {number} destW The width of the destination region. - * @param {number} destH The height of the destination region. + * This copies the source pixel from a Jimp image to every pixel in a + * destination rectangle within another Jimp image, without any alpha blending. */ -function copyPixelToRect( - srcImage: JimpInstance, - srcX: number, - srcY: number, - destImage: JimpInstance, - destX: number, - destY: number, - destW: number, - destH: number, -) { +function copyPixelToRect({ + srcImage, + srcX, + srcY, + destImage, + destX, + destY, + destW, + destH, +}: { + /** A Jimp image to copy pixels from. */ + srcImage: JimpInstance; + /** X position of the pixel to copy. */ + srcX: number; + /** Y position of the pixel to copy. */ + srcY: number; + /** A Jimp image to paste the pixels to. */ + destImage: JimpInstance; + /** X position to start pasting to (left). */ + destX: number; + /** Y position to start pasting to (top). */ + destY: number; + /** The width of the destination region. */ + destW: number; + /** The height of the destination region. */ + destH: number; +}) { const srcIndex = srcImage.getPixelIndex(srcX, srcY); - destImage.scan(destX, destY, destW, destH, (curDestX, curDestY, curDestIndex) => { + destImage.scan(destX, destY, destW, destH, (_, __, curDestIndex) => { destImage.bitmap.data[curDestIndex + 0] = srcImage.bitmap.data[srcIndex + 0]; destImage.bitmap.data[curDestIndex + 1] = srcImage.bitmap.data[srcIndex + 1]; destImage.bitmap.data[curDestIndex + 2] = srcImage.bitmap.data[srcIndex + 2]; diff --git a/packages/tile-extruder/src/index.ts b/packages/tile-extruder/src/index.ts index c1a59c9..47e7b1b 100644 --- a/packages/tile-extruder/src/index.ts +++ b/packages/tile-extruder/src/index.ts @@ -1,22 +1,9 @@ -/** - * Utils to extrude the tiles in a tileset by 1px. - * - * TODO: - * - Allow for customizable extrusion amount - * - Repacking large images? - * - Web app - */ - import { Jimp, JimpInstance } from "jimp"; import { copyPixels, copyPixelToRect } from "./copy-pixels"; -interface ExtrusionOptions { - margin?: number; - spacing?: number; - extrusion?: number; - color?: number | string; -} - +/** + * Jimp supports the following mime types but it doesn't export them. + */ type JimpMime = | "image/bmp" | "image/tiff" @@ -25,40 +12,67 @@ type JimpMime = | "image/jpeg" | "image/png"; -interface ImageOptions extends ExtrusionOptions { - mime?: JimpMime; -} +type ExtrusionOptions = { + /** The width of a tile in pixels. */ + tileWidth: number; + /** The height of a tile in pixels. */ + tileHeight: number; + /** + * The number of pixels between the tiles and the edge of the tileset image. + * Defaults to 0. + */ + margin?: number; + /** + * The number of pixels between neighboring tiles. Defaults to 0. + */ + spacing?: number; + /** + * The number of pixels to extrude the tiles. Defaults to 1. + */ + extrusion?: number; + /** + * The color to use for the background color, which only matters if there is + * margin or spacing. This is passed directly to jimp which takes RGBA hex or + * a CSS color string, e.g. '#FF0000'. This defaults to transparent white, + * 0xffffff00. + */ + color?: number | string; +}; /** - * Accepts an image path and returns a Promise that resolves to a Buffer containing the extruded - * tileset image. - * @param {integer} tileWidth - tile width in pixels. - * @param {integer} tileHeight - tile height in pixels. - * @param {string} inputPath - the path to the tileset you want to extrude. - * @param {object} [options] - optional settings. - * @param {string} [options.mime="image/png"] - the mime type that should be used for the buffer. - * Defaults to using the image's original mime type, and if not available, - * uses png. Supported mime options, see JimpMime. - * @param {integer} [options.margin=0] - number of pixels between tiles and the edge of the tileset - * image. - * @param {integer} [options.spacing=0] - number of pixels between neighboring tiles. - * @param {integer} [options.extrusion=1] - number of pixels to extrude the tiles. - * @param {number} [options.color=0xffffff00] - color to use for the background color, which only - * matters if there is margin or spacing. This is passed directly to jimp which takes RGBA hex or a - * CSS color string, e.g. '#FF0000'. This defaults to transparent white. - * @returns {Promise} - A promise that resolves to an image buffer, or rejects with an - * error. + * Accepts an image path and returns a Promise that resolves to a Buffer + * containing the extruded tileset image. */ -async function extrudeTilesetToBuffer( - tileWidth: number, - tileHeight: number, - inputPath: string, - { mime, margin, spacing, extrusion, color }: ImageOptions = {}, -) { - const options = { margin, spacing, extrusion, color }; +async function extrudeTilesetToBuffer({ + tileWidth, + tileHeight, + inputPath, + mime, + margin = 0, + spacing = 0, + extrusion = 1, + color = 0xffffff00, +}: ExtrusionOptions & { + /** + * The mime type that should be used for the buffer. Defaults to using the + * image's original mime type, and if not available, uses png. Supported mime + * options, see JimpMime. + */ + mime?: JimpMime; + /** The path to the tileset image to extrude. */ + inputPath: string; +}): Promise { let extrudedImage; try { - extrudedImage = await extrudeTilesetToJimp(tileWidth, tileHeight, inputPath, options); + extrudedImage = await extrudeTilesetToJimp({ + tileWidth, + tileHeight, + inputPath, + margin, + spacing, + extrusion, + color, + }); } catch (err) { console.error("Error extruding tileset: ", err); throw err; @@ -75,32 +89,36 @@ async function extrudeTilesetToBuffer( } /** - * Accepts an image path and saves out an extruded version of the tileset to `outputPath`. It - * returns a Promise that resolves when the file has finished saving. - * @param {integer} tileWidth - tile width in pixels. - * @param {integer} tileHeight - tile height in pixels. - * @param {string} inputPath - the path to the tileset you want to extrude. - * @param {string} outputPath - the path to output the extruded tileset image. - * @param {object} [options] - optional settings. - * @param {integer} [options.margin=0] - number of pixels between tiles and the edge of the tileset - * image. - * @param {integer} [options.spacing=0] - number of pixels between neighboring tiles. - * @param {integer} [options.extrusion=1] - number of pixels to extrude the tiles. - * @param {number} [options.color=0xffffff00] - color to use for the background color, which only - * matters if there is margin or spacing. This is passed directly to jimp which takes RGBA hex or a - * CSS color string, e.g. '#FF0000'. This defaults to transparent white. - * @returns {Promise} - A promise that resolves when finished saving, or rejects with an error. + * Accepts an image path and saves out an extruded version of the tileset to + * `outputPath`. It returns a Promise that resolves when the file has finished + * saving. */ -async function extrudeTilesetToImage( - tileWidth: number, - tileHeight: number, - inputPath: string, - outputPath: `${string}.${string}`, - options: ExtrusionOptions, -) { +async function extrudeTilesetToImage({ + tileWidth, + tileHeight, + inputPath, + outputPath, + margin = 0, + spacing = 0, + extrusion = 1, + color = 0xffffff00, +}: ExtrusionOptions & { + /** The path to the tileset image to extrude. */ + inputPath: string; + /** The path to save the extruded tileset image to. */ + outputPath: `${string}.${string}`; +}) { let extrudedImage; try { - extrudedImage = await extrudeTilesetToJimp(tileWidth, tileHeight, inputPath, options); + extrudedImage = await extrudeTilesetToJimp({ + tileWidth, + tileHeight, + inputPath, + margin, + spacing, + extrusion, + color, + }); } catch (err) { console.error("Error extruding tileset: ", err); throw err; @@ -114,30 +132,23 @@ async function extrudeTilesetToImage( } /** - * Accepts an image path and returns a Jimp image object containing the extruded image. This is - * exposed for advanced image processing purposes. For more common uses, see extrudeTilesetToImage - * or extrudeTilesetToBuffer. It returns a Promise that resolves when it is finished extruding the - * image. - * @param {integer} tileWidth - tile width in pixels. - * @param {integer} tileHeight - tile height in pixels. - * @param {string} inputPath - the path to the tileset you want to extrude. - * @param {object} [options] - optional settings. - * @param {integer} [options.margin=0] - number of pixels between tiles and the edge of the tileset - * image. - * @param {integer} [options.spacing=0] - number of pixels between neighboring tiles. - * @param {integer} [options.extrusion=1] - number of pixels to extrude the tiles. - * @param {number} [options.color=0xffffff00] - color to use for the background color, which only - * matters if there is margin or spacing. This is passed directly to jimp which takes RGBA hex or a - * CSS color string, e.g. '#FF0000'. This defaults to transparent white. - * @returns {Promise} - A promise that resolves to a Jimp image object, or rejects with an - * error. + * Accepts an image path and returns a Jimp image object containing the extruded + * image. This is exposed for advanced image processing purposes. For more + * common uses, see extrudeTilesetToImage or extrudeTilesetToBuffer. It returns + * a Promise that resolves when it is finished extruding the image. */ -async function extrudeTilesetToJimp( - tileWidth: number, - tileHeight: number, - inputPath: string, - { margin = 0, spacing = 0, color = 0xffffff00, extrusion = 1 }: ExtrusionOptions = {}, -): Promise { +async function extrudeTilesetToJimp({ + tileWidth, + tileHeight, + inputPath, + margin = 0, + spacing = 0, + extrusion = 1, + color = 0xffffff00, +}: ExtrusionOptions & { + /** The path to the tileset image to extrude. */ + inputPath: string; +}): Promise { let image: JimpInstance; try { image = (await Jimp.read(inputPath)) as JimpInstance; @@ -176,88 +187,118 @@ async function extrudeTilesetToJimp( const th = tileHeight; // Copy the tile. - copyPixels(image, srcX, srcY, tw, th, extrudedImage, destX + extrusion, destY + extrusion); + copyPixels({ + srcImage: image, + srcX, + srcY, + srcW: tw, + srcH: th, + destImage: extrudedImage, + destX: destX + extrusion, + destY: destY + extrusion, + }); for (let i = 0; i < extrusion; i++) { // Extrude the top row. - copyPixels(image, srcX, srcY, tw, 1, extrudedImage, destX + extrusion, destY + i); + copyPixels({ + srcImage: image, + srcX, + srcY, + srcW: tw, + srcH: 1, + destImage: extrudedImage, + destX: destX + extrusion, + destY: destY + i, + }); // Extrude the bottom row. - copyPixels( - image, + copyPixels({ + srcImage: image, srcX, - srcY + th - 1, - tw, - 1, - extrudedImage, - destX + extrusion, - destY + extrusion + th + (extrusion - i - 1), - ); + srcY: srcY + th - 1, + srcW: tw, + srcH: 1, + destImage: extrudedImage, + destX: destX + extrusion, + destY: destY + extrusion + th + (extrusion - i - 1), + }); // Extrude left column. - copyPixels(image, srcX, srcY, 1, th, extrudedImage, destX + i, destY + extrusion); + copyPixels({ + srcImage: image, + srcX, + srcY, + srcW: 1, + srcH: th, + destImage: extrudedImage, + destX: destX + i, + destY: destY + extrusion, + }); // Extrude the right column. - copyPixels( - image, - srcX + tw - 1, + copyPixels({ + srcImage: image, + srcX: srcX + tw - 1, srcY, - 1, - th, - extrudedImage, - destX + extrusion + tw + (extrusion - i - 1), - destY + extrusion, - ); + srcW: 1, + srcH: th, + destImage: extrudedImage, + destX: destX + extrusion + tw + (extrusion - i - 1), + destY: destY + extrusion, + }); } // Extrude the top left corner. - copyPixelToRect(image, srcX, srcY, extrudedImage, destX, destY, extrusion, extrusion); + copyPixelToRect({ + srcImage: image, + srcX, + srcY, + destImage: extrudedImage, + destX, + destY, + destW: extrusion, + destH: extrusion, + }); // Extrude the top right corner. - copyPixelToRect( - image, - srcX + tw - 1, + copyPixelToRect({ + srcImage: image, + srcX: srcX + tw - 1, srcY, - extrudedImage, - destX + extrusion + tw, + destImage: extrudedImage, + destX: destX + extrusion + tw, destY, - extrusion, - extrusion, - ); + destW: extrusion, + destH: extrusion, + }); // Extrude the bottom left corner. - copyPixelToRect( - image, + copyPixelToRect({ + srcImage: image, srcX, - srcY + th - 1, - extrudedImage, + srcY: srcY + th - 1, + destImage: extrudedImage, destX, - destY + extrusion + th, - extrusion, - extrusion, - ); + destY: destY + extrusion + th, + destW: extrusion, + destH: extrusion, + }); // Extrude the bottom right corner. - copyPixelToRect( - image, - srcX + tw - 1, - srcY + th - 1, - extrudedImage, - destX + extrusion + tw, - destY + extrusion + th, - extrusion, - extrusion, - ); + copyPixelToRect({ + srcImage: image, + srcX: srcX + tw - 1, + srcY: srcY + th - 1, + destImage: extrudedImage, + destX: destX + extrusion + tw, + destY: destY + extrusion + th, + destW: extrusion, + destH: extrusion, + }); } } return extrudedImage; } -export { - extrudeTilesetToBuffer, - extrudeTilesetToImage, - extrudeTilesetToJimp, - ExtrusionOptions, - ImageOptions, -}; +export { extrudeTilesetToBuffer, extrudeTilesetToImage, extrudeTilesetToJimp, ExtrusionOptions };