pixteroid
Version:
Pixteroid is a Node.js API designed for efficient image upscaling and restoration, powered by AI and utilizing the NCNN framework. It employs Real-ESRGAN and ESRGAN model weights to upscale and restore images, providing three distinct levels of detail and
89 lines (88 loc) • 3.18 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.upscale = upscale;
exports.upscaleAll = upscaleAll;
const child_process_1 = require("child_process");
const os_1 = require("os");
const path_1 = require("path");
function _nonZeroAssignment(percentage) {
const int = Math.floor((percentage * threads) / 100);
return int === 0 ? 1 : int;
}
function _commandConstrutor(executable, commandArgs) {
let commandline = `${executable}`;
Object.keys(commandArgs).forEach((option) => {
commandline += ` ${option} ${commandArgs[option]}`;
});
return commandline.replaceAll("\\", "/");
}
const binary = (0, path_1.join)(__dirname, "..") +
`/bin/ncnn/realesrgan-ncnn-vulkan${process.platform === "win32" ? ".exe" : ""}`;
const threads = (0, os_1.cpus)().length;
const decode = _nonZeroAssignment(10);
const proc = _nonZeroAssignment(65);
const encode = _nonZeroAssignment(25);
function upscale(input, output, level) {
input = (0, path_1.resolve)((0, path_1.relative)(process.cwd(), input));
output = (0, path_1.resolve)((0, path_1.relative)(process.cwd(), output));
const commandArgs = {
"-i": input,
"-o": output,
"-s": 4,
"-n": level,
"-j": `${decode}:${proc}:${encode}`,
};
const commandline = _commandConstrutor(binary, commandArgs);
return new Promise((resolve, reject) => {
(0, child_process_1.exec)(commandline)
.on("exit", (code, signal) => {
if (code === 0) {
resolve(true);
}
else {
reject(`Unexpected exit code: ${code} -|- signal: ${signal}\n${commandline}`);
}
})
.on("error", (err) => {
reject(err.message);
});
});
}
async function upscaleAll(inputs, basePath, level, batchSize = 2) {
console.log("Number of images in queue: " + inputs.length);
console.log("Number of cycles: " + Math.floor(inputs.length / batchSize));
console.log("Number of batches per cycle: " + batchSize);
const outputPromises = inputs.map((input) => {
return () => {
return new Promise((resolve, reject) => {
const output = (0, path_1.join)(basePath, (0, path_1.relative)(process.cwd(), input));
upscale(input, output, level)
.then((success) => {
if (success) {
resolve();
}
else {
reject("Upscale failed: " + input);
}
})
.catch((err) => {
reject(err);
});
});
};
});
const promiseBatches = [];
for (let i = 0; i < outputPromises.length; i += batchSize) {
promiseBatches.push(outputPromises.slice(i, i + batchSize));
}
for (const batch of promiseBatches) {
const activatedBatch = batch.map((func) => func());
try {
await Promise.all(activatedBatch);
}
catch (error) {
console.log(error);
process.exit(1);
}
}
}