random-image-generator-plus
Version:
8Crafter's Random Image Generator. This Node.js program generates images by setting each pixel to a randomly colored pixel.
117 lines (104 loc) • 5.4 kB
JavaScript
/**
* @import { Canvas } from "canvas";
*/
import { createCanvas } from "canvas";
/**
* The version of the program.
*/
export const format_version = "1.0.3";
/**
* Generates a random image of the specified dimensions and scale.
*
* @param {{ width?: number, height?: number, scale?: [x: number, y: number], grayscale?: boolean, format?: "jpg" | "jpeg" | "pdf" | "svg" | "png" | undefined, jpegOptions?: { chromaSubsampling?: boolean, progressive?: boolean, quality?: number } }} options The options for the generate command.
* @param {number} [options.width=128] The width of the image. Defaults to 128.
* @param {number} [options.height=128] The height of the image. Defaults to 128.
* @param {[x: number, y: number]} [options.scale=[1, 1]] The X and Y scale of the image, this specifies the size of each pixel, this will not affect the width or height of the image. Defaults to [1, 1]. Must be an integer of at least 1.
* @param {boolean} [options.grayscale=false] Whether to generate a grayscale image. Defaults to false.
* @param {"jpg" | "pdg" | "svg" | "png"} [options.format="png"] The format of the image, defaults to PNG.
* @param {{ chromaSubsampling?: boolean, progressive?: boolean, quality?: number }} [options.jpegOptions={}] The options for the JPEG image, only used if `options.format` is set to `jpg`.
* @returns {Buffer<ArrayBufferLike} The generated image as a buffer, its MIME type is `image/png` unless `options.format` is set to `jpg`, `pdg` or `svg`.
*
* @throws {TypeError} If the width or height is not an integer.
* @throws {RangeError} If the width or height is less than 0.
* @throws {RangeError} If the X or Y scale is less than 1.
*/
export function generateRandomImage(options = {}) {
// Check if the width is an integer.
if (options.width !== undefined && Math.floor(options.width) !== options.width) {
throw new TypeError("Width must be an integer.");
}
// Check if the width is at least 1.
if ((options.width ?? 128) < 0) {
throw new RangeError("Width must be at least 0.");
}
// Check if the height is an integer.
if (options.height !== undefined && Math.floor(options.height) !== options.height) {
throw new TypeError("Height must be an integer.");
}
// Check if the height is at least 1.
if ((options.height ?? 128) < 0) {
throw new RangeError("Height must be at least 0.");
}
// Check if the X scale is at least 1.
if ((options.scale?.[0] ?? 1) < 1) {
throw new RangeError("X scale must be at least 1.");
}
// Check if the Y scale is at least 1.
if ((options.scale?.[1] ?? 1) < 1) {
throw new RangeError("Y scale must be at least 1.");
}
/**
* The canvas object.
*
* @type {Canvas}
*/
const canvas = createCanvas(options.width ?? 128, options.height ?? 128, options.format?.toLowerCase() === "svg" ? "svg" : options.format?.toLowerCase() === "pdf" ? "pdf" : undefined);
/**
* The canvas context.
*
* @type {CanvasRenderingContext2D}
*/
const context = canvas.getContext("2d");
// Iterate over the x coordinates of the image.
for (let x = 0; x < (options.width ?? 128); x += options.scale?.[0] ?? 1) {
// Iterate over the y coordinates of the image.
for (let y = 0; y < (options.height ?? 128); y += options.scale?.[1] ?? 1) {
// If options.grayscale is true, generate a random grayscale image.
if (options.grayscale ?? false) {
const value = Math.floor(Math.random() * 256);
const r = value;
const g = value;
const b = value;
// Set the fill style to the generated color.
context.fillStyle = `rgb(${r},${g},${b})`;
// Fill the current pixel with the generated color.
context.fillRect(x, y, options.scale?.[0] ?? 1, options.scale?.[1] ?? 1);
// Continue to the next iteration of the loop.
continue;
}
// If options.grayscale is false, generate a random color image.
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
// Set the fill style to the generated color.
context.fillStyle = `rgb(${r},${g},${b})`;
// Fill the current pixel with the generated color.
context.fillRect(x, y, options.scale?.[0] ?? 1, options.scale?.[1] ?? 1);
}
}
/**
* The generated image as a buffer.
*
* @type {Buffer<ArrayBufferLike>}
*/
return canvas.toBuffer(
["jpg", "jpeg"].includes(options.format?.toLowerCase()) ? "image/jpeg" : options.format?.toLowerCase() === "pdf" ? "application/pdf" : options.format?.toLowerCase() === "svg" ? undefined : "image/png",
["jpg", "jpeg"].includes(options.format?.toLowerCase())
? {
chromaSubsampling: options.jpegOptions?.chromaSubsampling ?? false,
progressive: options.jpegOptions?.progressive ?? false,
quality: options.jpegOptions?.quality ?? 0.75,
}
: undefined
);
}