refactor(Multimedia): centralize Jimp configuration and enable WebP output
- Creates src/core/lib/Jimp.mjs to centralize Jimp instance with WebP support\n- Updates all image operations to use the centralized Jimp wrapper\n- Enables WEBP as an output format in 'Convert Image Format' operation\n- Adds quality support for WebP output
This commit is contained in:
parent
84ccd2f867
commit
e24006d809
21
src/core/lib/Jimp.mjs
Normal file
21
src/core/lib/Jimp.mjs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* Jimp image library with additional plugins.
|
||||||
|
*
|
||||||
|
* @author n1474335 [n1474335@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2024
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { Jimp as BaseJimp, JimpMime, PNGFilterType, ResizeStrategy, EdgeAction } from "jimp";
|
||||||
|
import webp from "@jimp/wasm-webp";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure Jimp with WebP support
|
||||||
|
*/
|
||||||
|
const Jimp = new BaseJimp({
|
||||||
|
plugins: [webp],
|
||||||
|
formats: [webp]
|
||||||
|
});
|
||||||
|
|
||||||
|
export { Jimp, JimpMime, PNGFilterType, ResizeStrategy, EdgeAction };
|
||||||
|
export default Jimp;
|
||||||
@ -16,7 +16,7 @@ import {
|
|||||||
measureText,
|
measureText,
|
||||||
measureTextHeight,
|
measureTextHeight,
|
||||||
loadFont,
|
loadFont,
|
||||||
} from "jimp";
|
} from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add Text To Image operation
|
* Add Text To Image operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Blur Image operation
|
* Blur Image operation
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import {
|
|||||||
ResizeStrategy,
|
ResizeStrategy,
|
||||||
HorizontalAlign,
|
HorizontalAlign,
|
||||||
VerticalAlign,
|
VerticalAlign,
|
||||||
} from "jimp";
|
} from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contain Image operation
|
* Contain Image operation
|
||||||
|
|||||||
@ -8,16 +8,7 @@ import Operation from "../Operation.mjs";
|
|||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { Jimp as BaseJimp, JimpMime, PNGFilterType } from "jimp";
|
import { Jimp, JimpMime, PNGFilterType } from "../lib/Jimp.mjs";
|
||||||
import webp from "@jimp/wasm-webp";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure Jimp with WebP support
|
|
||||||
*/
|
|
||||||
const Jimp = new BaseJimp({
|
|
||||||
plugins: [webp],
|
|
||||||
formats: [webp]
|
|
||||||
});
|
|
||||||
|
|
||||||
function canTranscodeViaCanvas() {
|
function canTranscodeViaCanvas() {
|
||||||
return (
|
return (
|
||||||
@ -31,7 +22,7 @@ function canTranscodeViaCanvas() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function transcodeViaCanvas(input, inputMime, outputMime, quality) {
|
async function transcodeViaCanvas(input, inputMime, outputMime, quality) {
|
||||||
const {Blob: BlobCtor, createImageBitmap: createImageBitmapFn, OffscreenCanvas: OffscreenCanvasCtor, document} =
|
const { Blob: BlobCtor, createImageBitmap: createImageBitmapFn, OffscreenCanvas: OffscreenCanvasCtor, document } =
|
||||||
globalThis;
|
globalThis;
|
||||||
|
|
||||||
const inputBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;
|
const inputBytes = input instanceof ArrayBuffer ? new Uint8Array(input) : input;
|
||||||
@ -52,7 +43,7 @@ async function transcodeViaCanvas(input, inputMime, outputMime, quality) {
|
|||||||
const ctx = canvas.getContext("2d");
|
const ctx = canvas.getContext("2d");
|
||||||
if (!ctx) throw new Error("Unable to initialise canvas context");
|
if (!ctx) throw new Error("Unable to initialise canvas context");
|
||||||
|
|
||||||
if (outputMime === "image/jpeg") {
|
if (outputMime === "image/jpeg" || outputMime === "image/webp") {
|
||||||
ctx.fillStyle = "#ffffff";
|
ctx.fillStyle = "#ffffff";
|
||||||
ctx.fillRect(0, 0, bitmap.width, bitmap.height);
|
ctx.fillRect(0, 0, bitmap.width, bitmap.height);
|
||||||
}
|
}
|
||||||
@ -98,7 +89,7 @@ class ConvertImageFormat extends Operation {
|
|||||||
this.name = "Convert Image Format";
|
this.name = "Convert Image Format";
|
||||||
this.module = "Image";
|
this.module = "Image";
|
||||||
this.description =
|
this.description =
|
||||||
"Converts an image between different formats. Supported output formats:<br><ul><li>Joint Photographic Experts Group (JPEG)</li><li>Portable Network Graphics (PNG)</li><li>Bitmap (BMP)</li><li>Tagged Image File Format (TIFF)</li></ul><br>Note: GIF and WebP files are supported for input, but cannot be outputted.";
|
"Converts an image between different formats. Supported output formats:<br><ul><li>Joint Photographic Experts Group (JPEG)</li><li>Portable Network Graphics (PNG)</li><li>Bitmap (BMP)</li><li>Tagged Image File Format (TIFF)</li><li>WebP</li></ul><br>Note: GIF files are supported for input, but cannot be outputted.";
|
||||||
this.infoURL = "https://wikipedia.org/wiki/Image_file_formats";
|
this.infoURL = "https://wikipedia.org/wiki/Image_file_formats";
|
||||||
this.inputType = "ArrayBuffer";
|
this.inputType = "ArrayBuffer";
|
||||||
this.outputType = "ArrayBuffer";
|
this.outputType = "ArrayBuffer";
|
||||||
@ -107,10 +98,10 @@ class ConvertImageFormat extends Operation {
|
|||||||
{
|
{
|
||||||
name: "Output Format",
|
name: "Output Format",
|
||||||
type: "option",
|
type: "option",
|
||||||
value: ["JPEG", "PNG", "BMP", "TIFF"],
|
value: ["JPEG", "PNG", "BMP", "TIFF", "WEBP"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "JPEG Quality",
|
name: "Quality (JPEG/WebP)",
|
||||||
type: "number",
|
type: "number",
|
||||||
value: 80,
|
value: 80,
|
||||||
min: 1,
|
min: 1,
|
||||||
@ -137,12 +128,13 @@ class ConvertImageFormat extends Operation {
|
|||||||
* @returns {byteArray}
|
* @returns {byteArray}
|
||||||
*/
|
*/
|
||||||
async run(input, args) {
|
async run(input, args) {
|
||||||
const [format, jpegQuality, pngFilterType, pngDeflateLevel] = args;
|
const [format, quality, pngFilterType, pngDeflateLevel] = args;
|
||||||
const formatMap = {
|
const formatMap = {
|
||||||
JPEG: JimpMime.jpeg,
|
JPEG: JimpMime.jpeg,
|
||||||
PNG: JimpMime.png,
|
PNG: JimpMime.png,
|
||||||
BMP: JimpMime.bmp,
|
BMP: JimpMime.bmp,
|
||||||
TIFF: JimpMime.tiff,
|
TIFF: JimpMime.tiff,
|
||||||
|
WEBP: "image/webp",
|
||||||
};
|
};
|
||||||
|
|
||||||
const pngFilterMap = {
|
const pngFilterMap = {
|
||||||
@ -167,8 +159,11 @@ class ConvertImageFormat extends Operation {
|
|||||||
canTranscodeViaCanvas()
|
canTranscodeViaCanvas()
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const outputMime = mime === JimpMime.jpeg ? "image/jpeg" : "image/png";
|
let outputMime;
|
||||||
const quality = outputMime === "image/jpeg" ? jpegQuality : undefined;
|
if (mime === JimpMime.jpeg) outputMime = "image/jpeg";
|
||||||
|
else if (mime === "image/webp") outputMime = "image/webp";
|
||||||
|
else outputMime = "image/png";
|
||||||
|
|
||||||
return await transcodeViaCanvas(input, inputMime, outputMime, quality);
|
return await transcodeViaCanvas(input, inputMime, outputMime, quality);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// If canvas fails, we can fall back to Jimp
|
// If canvas fails, we can fall back to Jimp
|
||||||
@ -185,8 +180,9 @@ class ConvertImageFormat extends Operation {
|
|||||||
let buffer;
|
let buffer;
|
||||||
switch (mime) {
|
switch (mime) {
|
||||||
case JimpMime.jpeg:
|
case JimpMime.jpeg:
|
||||||
|
case "image/webp":
|
||||||
buffer = await image.getBuffer(mime, {
|
buffer = await image.getBuffer(mime, {
|
||||||
quality: jpegQuality,
|
quality: quality,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case JimpMime.png:
|
case JimpMime.png:
|
||||||
|
|||||||
@ -15,7 +15,7 @@ import {
|
|||||||
ResizeStrategy,
|
ResizeStrategy,
|
||||||
HorizontalAlign,
|
HorizontalAlign,
|
||||||
VerticalAlign,
|
VerticalAlign,
|
||||||
} from "jimp";
|
} from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cover Image operation
|
* Cover Image operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crop Image operation
|
* Crop Image operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Dither operation
|
* Image Dither operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
import { fromBinary } from "../lib/Binary.mjs";
|
import { fromBinary } from "../lib/Binary.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { Jimp } from "jimp";
|
import { Jimp } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract LSB operation
|
* Extract LSB operation
|
||||||
|
|||||||
@ -7,7 +7,7 @@
|
|||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { Jimp } from "jimp";
|
import { Jimp } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
import { RGBA_DELIM_OPTIONS } from "../lib/Delim.mjs";
|
import { RGBA_DELIM_OPTIONS } from "../lib/Delim.mjs";
|
||||||
|
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flip Image operation
|
* Flip Image operation
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import Utils from "../Utils.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime, ResizeStrategy, rgbaToInt } from "jimp";
|
import { Jimp, JimpMime, ResizeStrategy, rgbaToInt } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate Image operation
|
* Generate Image operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Brightness / Contrast operation
|
* Image Brightness / Contrast operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Filter operation
|
* Image Filter operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Hue/Saturation/Lightness operation
|
* Image Hue/Saturation/Lightness operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image Opacity operation
|
* Image Opacity operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invert Image operation
|
* Invert Image operation
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import Operation from "../Operation.mjs";
|
|||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalise Image operation
|
* Normalise Image operation
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import Utils from "../Utils.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { runHash } from "../lib/Hash.mjs";
|
import { runHash } from "../lib/Hash.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { Jimp } from "jimp";
|
import { Jimp } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Randomize Colour Palette operation
|
* Randomize Colour Palette operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime, ResizeStrategy } from "jimp";
|
import { Jimp, JimpMime, ResizeStrategy } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resize Image operation
|
* Resize Image operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rotate Image operation
|
* Rotate Image operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { isWorkerEnvironment } from "../Utils.mjs";
|
import { isWorkerEnvironment } from "../Utils.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sharpen Image operation
|
* Sharpen Image operation
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import Operation from "../Operation.mjs";
|
|||||||
import OperationError from "../errors/OperationError.mjs";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { Jimp, JimpMime } from "jimp";
|
import { Jimp, JimpMime } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Split Colour Channels operation
|
* Split Colour Channels operation
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
|
|||||||
import Utils from "../Utils.mjs";
|
import Utils from "../Utils.mjs";
|
||||||
import { isImage } from "../lib/FileType.mjs";
|
import { isImage } from "../lib/FileType.mjs";
|
||||||
import { toBase64 } from "../lib/Base64.mjs";
|
import { toBase64 } from "../lib/Base64.mjs";
|
||||||
import { Jimp } from "jimp";
|
import { Jimp } from "../lib/Jimp.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* View Bit Plane operation
|
* View Bit Plane operation
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user