png2icons
Version:
Create Apple ICNS and Microsoft ICO files from PNG
217 lines (212 loc) • 6.42 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const fs_1 = require("fs");
const path_1 = require("path");
const PNG2ICONS = require("./png2icons");
/**
* Number of arguments.
*/
const argc = process.argv.length;
/**
* Name of "executable".
*/
const cli = path_1.parse(__filename).name;
/**
* Desired output format.
*/
let outputFormat;
/**
* Scaling algorithm to use.
*/
let scalingAlgorithm = PNG2ICONS.BICUBIC;
/**
* Log to console?
*/
let printInfo = false;
/**
* Names of scaling algorithms.
*/
const scalingAlgorithms = [
"Nearest Neighbor",
"Bilinear",
"Bicubic",
"Bezier",
"Hermite",
];
/**
* Simple logging to console.
* @param message The main message to log.
* @param optionalParams Additional messages to log.
*/
const consoleLogger = (message, ...optionalParams) => {
// Always log errors, regardless of printInfo. By convention all code must
// call this method with an Error as the *last* parameter if an error occured.
const err = optionalParams[optionalParams.length - 1];
if (err instanceof Error) {
console.error(message, ...optionalParams[0], "\n", ...optionalParams.slice(1, optionalParams.length - 1), err.stack);
}
else if (printInfo) {
console.log(message, ...optionalParams);
}
};
/**
* Print usage.
*/
function printUsage() {
const usage = `usage: ${cli} infile outfile format [-nn | - bl | -bc | -bz | -hm] [-i]
Don\'t append a file extension to outfile, it will be set automatically.
format (output format):
-icns Apple ICNS format, creates <outfile>.icns
-ico Windows ICO format, creates <outfile>.ico (contained icons as BMP)
-icop Windows ICO format, creates <outfile>.ico (contained icons as PNG)
-icowe Windows ICO format, creates <outfile>.ico (for Windows executables)
-all Create both ICNS and ICO format (ICO with BMP)
-allp Create both ICNS and ICO format (ICO with PNG)
-allwe Create both ICNS and ICO format (ICO for Windows executables)
Scaling algorithms:
-nn (Nearest Neighbor)
-bl (Bilinear)
-bc (Bicubic, default)
-bz (Bezier)
-hm (Hermite)
-bc2 (Bicubic, alternative faster version)
-i print messages`;
console.log(usage);
process.exit(1);
}
/**
* Get arguments.
* @param arg Argument to evaluate.
*/
function evalArg(arg) {
if (arg === "-nn") {
scalingAlgorithm = PNG2ICONS.NEAREST_NEIGHBOR;
}
else if (arg === "-bl") {
scalingAlgorithm = PNG2ICONS.BILINEAR;
}
else if (arg === "-bc") {
scalingAlgorithm = PNG2ICONS.BICUBIC;
}
else if (arg === "-bz") {
scalingAlgorithm = PNG2ICONS.BEZIER;
}
else if (arg === "-hm") {
scalingAlgorithm = PNG2ICONS.HERMITE;
}
else if (arg === "-bc2") {
scalingAlgorithm = PNG2ICONS.BICUBIC2;
// } else if (arg === "-bl2") {
// scalingAlgorithm = PNG2ICONS.BILINEAR2;
}
else if (arg === "-i") {
printInfo = true;
}
}
// Invalid argc or unknown args.
if ((argc < 5) || (argc > 7)) {
printUsage();
}
outputFormat = process.argv[4];
if (["-icns", "-ico", "-icop", "-icowe", "-all", "-allp", "-allwe"].indexOf(outputFormat) === -1) {
printUsage();
}
for (let i = 5; i < argc; i++) {
if (["-nn", "-bl", "-bc", "-bz", "-hm", "-bc2", /*"-bl2",*/ "-i"].indexOf(process.argv[i]) === -1) {
printUsage();
}
}
// Either only debug or only a scaling algorithm is set.
evalArg(process.argv[5]);
if (argc === 7) {
// -i used twice
if (printInfo && (process.argv[6] === "-i")) {
printUsage();
}
else {
evalArg(process.argv[6]);
// Two scaling algorithms instead of -i given
if (!printInfo) {
printUsage();
}
}
}
/**
* An array for all tasks to be executed.
*/
const tasks = [];
/**
* Create a converter task.
* @param format Console info for current task.
* @param png Use PNG format.
* @param forWinExe Create special ICO for Windows executables.
* @param fileExt File extension of output file.
* @param fn Converter task function.
* @returns A converter Task.
*/
function getTask(format, png, forWinExe, fileExt, fn) {
return {
Format: format,
PNG: png,
ForWinExe: forWinExe,
FileExt: fileExt,
TaskFn: fn,
};
}
if (outputFormat === "-icns") {
tasks.push(getTask("ICNS", true, false, "icns", PNG2ICONS.createICNS));
}
else if (outputFormat === "-ico") {
tasks.push(getTask("ICO (BMP)", false, false, "ico", PNG2ICONS.createICO));
}
else if (outputFormat === "-icop") {
tasks.push(getTask("ICO (PNG)", true, false, "ico", PNG2ICONS.createICO));
}
else if (outputFormat === "-icowe") {
tasks.push(getTask("ICO (for Windows executable)", false, true, "ico", PNG2ICONS.createICO));
}
else if (outputFormat === "-all") {
tasks.push(getTask("ICNS", true, false, "icns", PNG2ICONS.createICNS));
tasks.push(getTask("ICO (BMP)", false, false, "ico", PNG2ICONS.createICO));
}
else if (outputFormat === "-allp") {
tasks.push(getTask("ICNS", true, false, "icns", PNG2ICONS.createICNS));
tasks.push(getTask("ICO (PNG)", true, false, "ico", PNG2ICONS.createICO));
}
else if (outputFormat === "-allwe") {
tasks.push(getTask("ICNS", true, false, "icns", PNG2ICONS.createICNS));
tasks.push(getTask("ICO (for Windows executable)", false, true, "ico", PNG2ICONS.createICO));
}
else { // ??
printUsage();
}
PNG2ICONS.setLogger(consoleLogger);
/**
* The input file (PNG format).
*/
const inputFile = path_1.resolve(process.argv[2]);
/**
* The output file name (without extension).
*/
const outputFileStub = path_1.resolve(process.argv[3]);
/**
* The buffer containing the complete content of the input PNG file.
*/
const input = fs_1.readFileSync(path_1.resolve(inputFile));
for (let i = 0; i < tasks.length; i++) {
const task = tasks[i];
const taskInfo = `${cli}
input: ${inputFile}
output: ${outputFileStub}.${task.FileExt}
scaling: ${scalingAlgorithms[scalingAlgorithm]}
format: ${task.Format}`;
consoleLogger(taskInfo);
const output = task.TaskFn(input, scalingAlgorithm, 0, task.PNG, task.ForWinExe);
if (output) {
fs_1.writeFileSync(`${outputFileStub}.${task.FileExt}`, output);
}
if ((printInfo) && (tasks.length > 1) && (i < tasks.length - 1)) {
consoleLogger("");
}
}