metaplex/js/packages/cli/src/commands/createArt.ts

62 lines
1.8 KiB
TypeScript

import fs from 'fs';
import canvas from 'canvas';
import imagemin from 'imagemin';
import imageminPngquant from 'imagemin-pngquant';
import log from 'loglevel';
import { readJsonFile, sleep } from '../helpers/various';
import { ASSETS_DIRECTORY, TRAITS_DIRECTORY } from '../helpers/metadata';
const { createCanvas, loadImage } = canvas;
const createImage = async (order = [], image, width, height) => {
const canvas = createCanvas(width, height);
const context = canvas.getContext('2d');
const ID = parseInt(image.id, 10) - 1;
await Promise.all(
order.map(async cur => {
const imageLocation = `${TRAITS_DIRECTORY}/${cur}/${image[cur]}`;
const loadedImage = await loadImage(imageLocation);
context.patternQuality = 'best';
context.quality = 'best';
context.drawImage(loadedImage, 0, 0, width, height);
}),
);
const buffer = canvas.toBuffer('image/png');
const optimizedImage = await imagemin.buffer(buffer, {
plugins: [
imageminPngquant({
quality: [0.6, 0.95],
}),
],
});
log.info(`Placed ${ID}.png into the ${ASSETS_DIRECTORY}`);
fs.writeFileSync(`${ASSETS_DIRECTORY}/${ID}.png`, optimizedImage);
};
export async function createGenerativeArt(
configLocation: string,
randomizedSets,
) {
const { order, width, height } = await readJsonFile(configLocation);
const PROCESSING_LENGTH: number = 10;
const processImage = async (marker = 0) => {
const slice = randomizedSets.slice(marker, marker + PROCESSING_LENGTH + 1);
// generate images for the portion
await Promise.all(
slice.map(async image => {
await createImage(order, image, width, height);
}),
);
marker += PROCESSING_LENGTH;
await sleep(1000);
if (marker < randomizedSets.length - 1) {
processImage(marker);
}
};
// recurse until completion
processImage();
}