interlinked/source/interlinked.ts

133 lines
3.1 KiB
TypeScript
Raw Normal View History

2022-03-07 15:33:44 +00:00
import fsp from 'node:fs/promises';
import path from 'node:path';
import {performance} from 'node:perf_hooks';
import {execa} from 'execa';
2022-03-09 21:27:29 +00:00
import meow from 'meow';
2022-03-07 15:33:44 +00:00
import {Crop} from './gegl/exports.js';
2022-03-07 16:33:04 +00:00
import Project from './project.js';
2022-03-07 15:33:44 +00:00
2022-03-11 17:47:38 +00:00
import p2022 from './2022/projects.js';
2022-03-07 16:37:45 +00:00
2022-03-07 15:33:44 +00:00
async function main(): Promise<void> {
2022-03-09 21:27:29 +00:00
const cli = meow(
`
Options
2022-03-11 17:29:06 +00:00
--filter <name> Only render projects starting with <name>.
2022-03-09 21:27:29 +00:00
--include-defaults Include default GEGL operation parameters.
--no-render Don't render any images.
`,
{
flags: {
filter: {
2022-03-09 21:33:14 +00:00
default: '',
type: 'string',
},
2022-03-09 21:27:29 +00:00
includeDefaults: {
default: false,
type: 'boolean',
},
render: {
default: true,
type: 'boolean',
},
},
importMeta: import.meta,
},
);
const includeDefaults = cli.flags.includeDefaults;
const noRender = !cli.flags.render;
2022-03-07 21:46:09 +00:00
2022-03-11 17:47:38 +00:00
const projects: Project[] = [...p2022].filter((project) =>
project.name.startsWith(cli.flags.filter),
);
2022-03-07 15:33:44 +00:00
for (const {
createInputImage,
name,
operations,
resolution,
resetAlpha,
} of projects) {
2022-03-07 15:33:44 +00:00
const dataStart = performance.now();
const {width, height} = resolution;
const baseDir = path.resolve(`./output/${name}`);
await fsp.mkdir(baseDir, {recursive: true});
console.log(`# ${name}`);
console.log(`* ${width}x${height}`);
console.log(`* ${operations.length} operations`);
const graph = operations.flatMap((operation) => {
2022-03-07 21:46:09 +00:00
const graph = operation.graph(includeDefaults);
2022-03-07 15:33:44 +00:00
if (operation.appendCrop) {
2022-03-07 21:46:09 +00:00
graph.push(...new Crop({height, width}).graph(includeDefaults));
2022-03-07 15:33:44 +00:00
}
return graph;
});
const prettyGraph = graph.map((operation) =>
operation.startsWith('gegl:') ? `\n${operation}\n` : ` ${operation}\n`,
);
const graphFile = `${name}.txt`;
const outputFile = `${name}.png`;
2022-03-08 22:00:01 +00:00
const compressedFile = `${outputFile.slice(0, -4)}.jpeg`;
2022-03-07 15:33:44 +00:00
console.log(`* Writing ${graphFile}`);
await fsp.writeFile(
path.join(baseDir, graphFile),
prettyGraph.join('').trimStart(),
);
2022-03-07 21:42:15 +00:00
if (noRender) {
console.log(`* Skipped ${outputFile}`);
} else {
const fullOutputFile = path.join(baseDir, outputFile);
if (createInputImage) {
2022-10-02 21:50:51 +00:00
await execa('convert', [
'-size',
`${width}x${height}`,
'xc:white',
fullOutputFile,
]);
}
2022-03-07 21:42:15 +00:00
console.log(`* Writing ${outputFile}`);
await execa('gegl', [
...(createInputImage ? ['-i', fullOutputFile] : []),
2022-03-07 21:42:15 +00:00
'-o',
fullOutputFile,
2022-03-07 21:42:15 +00:00
'--',
...graph,
]);
2022-03-08 22:00:01 +00:00
if (resetAlpha) {
await execa('convert', [
fullOutputFile,
'-alpha',
'Off',
fullOutputFile,
]);
}
2022-03-08 22:00:01 +00:00
console.log(`* Writing ${compressedFile}`);
2022-10-02 21:50:51 +00:00
await execa('convert', [
fullOutputFile,
2022-03-08 22:00:01 +00:00
'-quality',
'92',
path.join(baseDir, compressedFile),
]);
2022-03-07 21:42:15 +00:00
}
2022-03-07 15:33:44 +00:00
const time = (performance.now() - dataStart).toFixed(2);
console.log(`* Generated in ${time}ms`);
}
}
void main();