Converted codebase to typescript.
Added new feature, custom page sizes. Use arguments -w,--width and -l,--length to specify the size in inches. Still defaults to 8.5x11in
This commit is contained in:
parent
4120e19291
commit
0001f73329
File diff suppressed because it is too large
Load Diff
14
package.json
14
package.json
|
@ -1,10 +1,12 @@
|
|||
{
|
||||
"name": "v2f",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.0",
|
||||
"description": "Turn a video into strips of precise 16mm-size stills",
|
||||
"main": "v2f.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build": "./node_modules/.bin/nexe ./ --build",
|
||||
"compile": "./node_modules/.bin/tsc ./src/v2f.ts --outFile ./v2f.js --noImplicitAny --lib ES2017 --lib ES2016 -t ES2016"
|
||||
},
|
||||
"author": "mmcwilliams",
|
||||
"license": "MIT",
|
||||
|
@ -17,7 +19,13 @@
|
|||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"async": "^2.5.0",
|
||||
"async": "^2.6.2",
|
||||
"commander": "^2.11.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^11.13.4",
|
||||
"jsdoc-to-markdown": "^4.0.1",
|
||||
"nexe": "^3.1.0",
|
||||
"typescript": "^3.4.3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,225 @@
|
|||
'use strict'
|
||||
|
||||
const cmd = require('commander')
|
||||
const async = require('async')
|
||||
const exec = require('child_process').exec
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
const os = require('os')
|
||||
|
||||
const osTmp : string = os.tmpdir()
|
||||
const TMP : string = path.join(osTmp, '/v2f/')
|
||||
|
||||
class Dimensions{
|
||||
h : number;
|
||||
w : number;
|
||||
o : number;
|
||||
dpi : number;
|
||||
film : any;
|
||||
|
||||
constructor (filmStr : string, dpi : number) {
|
||||
const IN : number = dpi / 25.4
|
||||
const film : any = this._gauge(filmStr)
|
||||
|
||||
this.h = Math.round(film.h * IN) //frame height
|
||||
this.w = Math.round(film.w * IN) //frame width
|
||||
this.o = Math.round(film.o * IN) //space between columns
|
||||
this.dpi = dpi
|
||||
this.film = film
|
||||
}
|
||||
|
||||
_gauge (film : string) {
|
||||
if (film === '16mm') {
|
||||
return {
|
||||
h: 7.62,
|
||||
w : 10.5,
|
||||
o : 16
|
||||
}
|
||||
} else if (film === 'super16'){
|
||||
return {
|
||||
h: 7.62,
|
||||
w : 12.75,
|
||||
o : 16
|
||||
}
|
||||
} else if (film === '35mm') {
|
||||
return {
|
||||
h : 19.05,
|
||||
w : 22,
|
||||
o : 35
|
||||
}
|
||||
} else {
|
||||
error('Film type not found, see --help for more info')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @function
|
||||
* @param {Object} Commander object
|
||||
*/
|
||||
function initialize (command : any) {
|
||||
const dpi : number = command.dpi || 300
|
||||
const film : string = command.film || '16mm'
|
||||
const input : string = command.input || command.args[0] || error('No input file, see --help for more info')
|
||||
const output : string = command.output || command.args[1] || error('No ouput directory, see --help for more info')
|
||||
const dim : any = new Dimensions(film, dpi)
|
||||
const pageW : number = command.width || 8.5
|
||||
const pageL : number = command.length || 11
|
||||
|
||||
if (!fs.existsSync(input)) error(`Video "${input}" cannot be found`)
|
||||
|
||||
async.series([
|
||||
(next : any)=> {
|
||||
convert(input, dim, next)
|
||||
},
|
||||
(next : any) => {
|
||||
stitch(output, dim, next, pageW, pageL)
|
||||
},
|
||||
cleanup
|
||||
], () => {
|
||||
console.log(`Finished creating pages`)
|
||||
})
|
||||
}
|
||||
|
||||
/** *
|
||||
* Create image sequence from source video, using
|
||||
*
|
||||
* @function
|
||||
* @param {String} input file path (absolute)
|
||||
* @param {Integer} dpi target printing dpi
|
||||
* @param {Integer} length strip length in frames
|
||||
*
|
||||
*/
|
||||
function convert (input : string, dim : any, next : any) {
|
||||
const file : string = input.split('/').pop()
|
||||
const execStr : string = `avconv -i "${input}" -s ${dim.w}x${dim.h} -qscale 1 "${TMP}v2f_sequence_%04d.jpg"`
|
||||
|
||||
console.log(`Converting ${file}...`)
|
||||
console.log(`Exporting all frames with aspect ratio: ${dim.w / dim.h}...`)
|
||||
|
||||
if (!fs.existsSync(TMP)) fs.mkdirSync(TMP)
|
||||
|
||||
exec(execStr, (ste : any, std : string) => {
|
||||
if (ste) {
|
||||
return error(ste)
|
||||
}
|
||||
console.log('Frames exported successfully!')
|
||||
next()
|
||||
})
|
||||
}
|
||||
|
||||
/** *
|
||||
* Stitch rendered frames into strips
|
||||
|
||||
* @function
|
||||
* @param {String} output Path of folder containing frames
|
||||
* @param {Object} dim Dimensions object
|
||||
* @param {Function} next Async lib callback function
|
||||
* @param {Integer} pageW Page width in inches
|
||||
* @param {Integer} pageL Page length in inches
|
||||
*
|
||||
*/
|
||||
function stitch (output : string, dim : any, next : any, pageW : number, pageL : number) {
|
||||
const length : number = Math.floor((pageL * dim.dpi) / dim.h) - 1
|
||||
const width : number = Math.floor((pageW * dim.dpi / dim.o)) - 1
|
||||
const loc : string = TMP.substring(0, TMP.length - 1)
|
||||
const diff : number = Math.round((dim.o - dim.w) / 2)
|
||||
let page : number = 0
|
||||
let pageCount : number = 0
|
||||
let cmd : string = `find "${loc}" -type f -name "v2f_sequence_*.jpg"`
|
||||
|
||||
console.log('Stitching frames into sheets...')
|
||||
console.log(`Sheets will contain ${width}x${length} frames...`)
|
||||
|
||||
exec(cmd, (ste : any, std : string) => {
|
||||
if (ste) {
|
||||
return error(ste)
|
||||
}
|
||||
let jobs : any[] = []
|
||||
let cmds : string[] = []
|
||||
let frames : string[] = std.split('\n')
|
||||
let execStr : string = 'montage '
|
||||
let pagePath : string = ``
|
||||
let i : number = 0
|
||||
|
||||
frames = frames.filter((elem : string) => {
|
||||
if (elem.indexOf('find: ') === -1) {
|
||||
return elem
|
||||
}
|
||||
})
|
||||
frames.sort()
|
||||
for (let frame of frames) {
|
||||
execStr += `${frame} `
|
||||
if ((i + 1) % (width * length) === 0 || i === frames.length - 1) {
|
||||
pagePath = path.join(output, `./page_${pad(page)}.jpg`)
|
||||
execStr += `\ -tile 1x${length} -geometry ${dim.w}x${dim.h}+${diff}+0 miff:- |\ \nmontage - -geometry +0+0 -tile ${width}x1 -density ${dim.dpi} "${pagePath}"`
|
||||
cmds.push(execStr)
|
||||
execStr = 'montage '
|
||||
page++
|
||||
}
|
||||
i++
|
||||
}
|
||||
jobs = cmds.map((cmd : string) => {
|
||||
return (cb : any) => {
|
||||
exec(cmd, (err : any, std : string, ste : string) => {
|
||||
if (err) {
|
||||
return error(err)
|
||||
}
|
||||
console.log(`Created page of ${width}x${length} frames!`)
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
async.series(jobs, next)
|
||||
})
|
||||
}
|
||||
|
||||
function cleanup (next : any) {
|
||||
console.log('Cleaning up...');
|
||||
exec(`rm -r "${TMP}"`, (err : any) => {
|
||||
if (err) console.error(err)
|
||||
if (next) next()
|
||||
})
|
||||
}
|
||||
|
||||
function pad (n : number) {
|
||||
return ('00000' + n).slice(-5)
|
||||
}
|
||||
|
||||
var error = function (err : any) {
|
||||
if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--verbose') !== -1){
|
||||
console.error(err)
|
||||
} else {
|
||||
console.error('Error running program. Run in verbose mode for more info (-v,--verbose)')
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
error(err)
|
||||
})
|
||||
|
||||
//convert(process.argv[2], process.argv[3])
|
||||
|
||||
//fix for nexe
|
||||
let args = [].concat(process.argv)
|
||||
if (args[1].indexOf('v2f.js') === -1) {
|
||||
args.reverse()
|
||||
args.push('node')
|
||||
args.reverse()
|
||||
}
|
||||
|
||||
cmd.arguments('<input> <output>')
|
||||
.version('1.1.0')
|
||||
.option('-i, --input <path>', 'Video source to print to film strip, anything that avconv can read')
|
||||
.option('-o, --output <path>', 'Output directory, will render images on specified page size')
|
||||
.option('-d, --dpi <dpi>', 'DPI output pages')
|
||||
.option('-f, --film <gauge>', 'Choose film gauge: 16mm, super16, 35mm')
|
||||
.option('-w, --width <inches>', 'Output page width, in inches. Default 8.5')
|
||||
.option('-l, --length <inches>', 'Output page length, in inches. Default 11')
|
||||
.option('-v, --verbose', 'Run in verbose mode')
|
||||
.parse(args)
|
||||
|
||||
initialize(cmd)
|
|
@ -1,106 +1,101 @@
|
|||
/*jshint strict: true, esversion:6, node: true, asi: true*/
|
||||
|
||||
'use strict'
|
||||
const cmd = require('commander')
|
||||
const async = require('async')
|
||||
const exec = require('child_process').exec
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const TMP = '/tmp/v2f/'
|
||||
|
||||
class Dimensions{
|
||||
constructor (filmStr, dpi) {
|
||||
const IN = dpi / 25.4
|
||||
const film = this._gauge(filmStr)
|
||||
|
||||
this.h = Math.round(film.h * IN) //frame height
|
||||
this.w = Math.round(film.w * IN) //frame width
|
||||
this.o = Math.round(film.o * IN) //space between columns
|
||||
this.dpi = dpi
|
||||
this.film = film
|
||||
}
|
||||
|
||||
_gauge (film) {
|
||||
if (film === '16mm') {
|
||||
return {
|
||||
h: 7.62,
|
||||
w : 10.5,
|
||||
o : 16
|
||||
}
|
||||
} else if (film === 'super16'){
|
||||
return {
|
||||
h: 7.62,
|
||||
w : 12.75,
|
||||
o : 16
|
||||
}
|
||||
} else if (film === '35mm') {
|
||||
return {
|
||||
h : 19.05,
|
||||
w : 22,
|
||||
o : 35
|
||||
}
|
||||
} else {
|
||||
error('Film type not found, see --help for more info')
|
||||
}
|
||||
}
|
||||
'use strict';
|
||||
const cmd = require('commander');
|
||||
const async = require('async');
|
||||
const exec = require('child_process').exec;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const os = require('os');
|
||||
const osTmp = os.tmpdir();
|
||||
const TMP = path.join(osTmp, '/v2f/');
|
||||
class Dimensions {
|
||||
constructor(filmStr, dpi) {
|
||||
const IN = dpi / 25.4;
|
||||
const film = this._gauge(filmStr);
|
||||
this.h = Math.round(film.h * IN); //frame height
|
||||
this.w = Math.round(film.w * IN); //frame width
|
||||
this.o = Math.round(film.o * IN); //space between columns
|
||||
this.dpi = dpi;
|
||||
this.film = film;
|
||||
}
|
||||
_gauge(film) {
|
||||
if (film === '16mm') {
|
||||
return {
|
||||
h: 7.62,
|
||||
w: 10.5,
|
||||
o: 16
|
||||
};
|
||||
}
|
||||
else if (film === 'super16') {
|
||||
return {
|
||||
h: 7.62,
|
||||
w: 12.75,
|
||||
o: 16
|
||||
};
|
||||
}
|
||||
else if (film === '35mm') {
|
||||
return {
|
||||
h: 19.05,
|
||||
w: 22,
|
||||
o: 35
|
||||
};
|
||||
}
|
||||
else {
|
||||
error('Film type not found, see --help for more info');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*
|
||||
* @function
|
||||
* @param {Object} Commander object
|
||||
*/
|
||||
function initialize (command) {
|
||||
const dpi = command.dpi || 300
|
||||
const film = command.film || '16mm'
|
||||
const input = command.input || command.args[0] || error('No input file, see --help for more info')
|
||||
const output = command.output || command.args[1] || error('No ouput directory, see --help for more info')
|
||||
const dim = new Dimensions(film, dpi)
|
||||
|
||||
if (!fs.existsSync(input)) error(`Video "${input}" cannot be found`)
|
||||
|
||||
async.series([
|
||||
next => {
|
||||
convert(input, dim, next)
|
||||
},
|
||||
next => {
|
||||
stitch(output, dim, next)
|
||||
},
|
||||
cleanup
|
||||
], () => {
|
||||
console.log(`Finished creating pages`)
|
||||
})
|
||||
function initialize(command) {
|
||||
const dpi = command.dpi || 300;
|
||||
const film = command.film || '16mm';
|
||||
const input = command.input || command.args[0] || error('No input file, see --help for more info');
|
||||
const output = command.output || command.args[1] || error('No ouput directory, see --help for more info');
|
||||
const dim = new Dimensions(film, dpi);
|
||||
const pageW = command.width || 8.5;
|
||||
const pageL = command.length || 11;
|
||||
if (!fs.existsSync(input))
|
||||
error(`Video "${input}" cannot be found`);
|
||||
async.series([
|
||||
(next) => {
|
||||
convert(input, dim, next);
|
||||
},
|
||||
(next) => {
|
||||
stitch(output, dim, next, pageW, pageL);
|
||||
},
|
||||
cleanup
|
||||
], () => {
|
||||
console.log(`Finished creating pages`);
|
||||
});
|
||||
}
|
||||
|
||||
/** *
|
||||
* Create image sequence from source video, using
|
||||
*
|
||||
*
|
||||
* @function
|
||||
* @param {String} input file path (absolute)
|
||||
* @param {Integer} dpi target printing dpi
|
||||
* @param {Integer} length strip length in frames
|
||||
*
|
||||
*
|
||||
*/
|
||||
function convert (input, dim, next) {
|
||||
const file = input.split('/').pop()
|
||||
const execStr = `avconv -i "${input}" -s ${dim.w}x${dim.h} -qscale 1 "${TMP}v2f_sequence_%04d.jpg"`
|
||||
|
||||
console.log(`Converting ${file}...`)
|
||||
console.log(`Exporting all frames with aspect ratio: ${dim.w / dim.h}...`)
|
||||
|
||||
if (!fs.existsSync(TMP)) fs.mkdirSync(TMP)
|
||||
|
||||
exec(execStr, (ste, std) => {
|
||||
if (ste) {
|
||||
return error(ste)
|
||||
}
|
||||
console.log('Frames exported successfully!')
|
||||
next()
|
||||
})
|
||||
function convert(input, dim, next) {
|
||||
const file = input.split('/').pop();
|
||||
const execStr = `avconv -i "${input}" -s ${dim.w}x${dim.h} -qscale 1 "${TMP}v2f_sequence_%04d.jpg"`;
|
||||
console.log(`Converting ${file}...`);
|
||||
console.log(`Exporting all frames with aspect ratio: ${dim.w / dim.h}...`);
|
||||
if (!fs.existsSync(TMP))
|
||||
fs.mkdirSync(TMP);
|
||||
exec(execStr, (ste, std) => {
|
||||
if (ste) {
|
||||
return error(ste);
|
||||
}
|
||||
console.log('Frames exported successfully!');
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
/** *
|
||||
* Stitch rendered frames into strips
|
||||
|
||||
|
@ -108,105 +103,101 @@ function convert (input, dim, next) {
|
|||
* @param {String} output Path of folder containing frames
|
||||
* @param {Object} dim Dimensions object
|
||||
* @param {Function} next Async lib callback function
|
||||
*
|
||||
* @param {Integer} pageW Page width in inches
|
||||
* @param {Integer} pageL Page length in inches
|
||||
*
|
||||
*/
|
||||
function stitch (output, dim, next) {
|
||||
const length = Math.floor((11 * dim.dpi) / dim.h) - 1
|
||||
const width = Math.floor((8.5 * dim.dpi / dim.o)) - 1
|
||||
const loc = TMP.substring(0, TMP.length - 1)
|
||||
const diff = Math.round((dim.o - dim.w) / 2)
|
||||
let page = 0
|
||||
let pageCount = 0
|
||||
let cmd = `find "${loc}" -type f -name "v2f_sequence_*.jpg"`
|
||||
|
||||
console.log('Stitching frames into sheets...')
|
||||
console.log(`Sheets will contain ${width}x${length} frames...`)
|
||||
|
||||
exec(cmd, (ste, std) => {
|
||||
if (ste) {
|
||||
return error(ste)
|
||||
}
|
||||
let jobs = []
|
||||
let cmds = []
|
||||
let frames = std.split('\n')
|
||||
let execStr = 'montage '
|
||||
let pagePath = ``
|
||||
let i = 0
|
||||
|
||||
frames = frames.filter(elem => {
|
||||
if (elem.indexOf('find: ') === -1) {
|
||||
return elem
|
||||
}
|
||||
})
|
||||
frames.sort()
|
||||
for (let frame of frames) {
|
||||
execStr += `${frame} `
|
||||
if ((i + 1) % (width * length) === 0 || i === frames.length - 1) {
|
||||
pagePath = path.join(output, `./page_${pad(page)}.jpg`)
|
||||
execStr += `\ -tile 1x${length} -geometry ${dim.w}x${dim.h}+${diff}+0 miff:- |\ \nmontage - -geometry +0+0 -tile ${width}x1 -density ${dim.dpi} "${pagePath}"`
|
||||
cmds.push(execStr)
|
||||
execStr = 'montage '
|
||||
page++
|
||||
}
|
||||
i++
|
||||
}
|
||||
jobs = cmds.map(cmd => {
|
||||
return cb => {
|
||||
exec(cmd, (err, std, ste) => {
|
||||
if (err) {
|
||||
return error(err)
|
||||
}
|
||||
console.log(`Created page of ${width}x${length} frames!`)
|
||||
cb()
|
||||
})
|
||||
}
|
||||
})
|
||||
async.series(jobs, next)
|
||||
})
|
||||
function stitch(output, dim, next, pageW, pageL) {
|
||||
const length = Math.floor((pageL * dim.dpi) / dim.h) - 1;
|
||||
const width = Math.floor((pageW * dim.dpi / dim.o)) - 1;
|
||||
const loc = TMP.substring(0, TMP.length - 1);
|
||||
const diff = Math.round((dim.o - dim.w) / 2);
|
||||
let page = 0;
|
||||
let pageCount = 0;
|
||||
let cmd = `find "${loc}" -type f -name "v2f_sequence_*.jpg"`;
|
||||
console.log('Stitching frames into sheets...');
|
||||
console.log(`Sheets will contain ${width}x${length} frames...`);
|
||||
exec(cmd, (ste, std) => {
|
||||
if (ste) {
|
||||
return error(ste);
|
||||
}
|
||||
let jobs = [];
|
||||
let cmds = [];
|
||||
let frames = std.split('\n');
|
||||
let execStr = 'montage ';
|
||||
let pagePath = ``;
|
||||
let i = 0;
|
||||
frames = frames.filter((elem) => {
|
||||
if (elem.indexOf('find: ') === -1) {
|
||||
return elem;
|
||||
}
|
||||
});
|
||||
frames.sort();
|
||||
for (let frame of frames) {
|
||||
execStr += `${frame} `;
|
||||
if ((i + 1) % (width * length) === 0 || i === frames.length - 1) {
|
||||
pagePath = path.join(output, `./page_${pad(page)}.jpg`);
|
||||
execStr += `\ -tile 1x${length} -geometry ${dim.w}x${dim.h}+${diff}+0 miff:- |\ \nmontage - -geometry +0+0 -tile ${width}x1 -density ${dim.dpi} "${pagePath}"`;
|
||||
cmds.push(execStr);
|
||||
execStr = 'montage ';
|
||||
page++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
jobs = cmds.map((cmd) => {
|
||||
return (cb) => {
|
||||
exec(cmd, (err, std, ste) => {
|
||||
if (err) {
|
||||
return error(err);
|
||||
}
|
||||
console.log(`Created page of ${width}x${length} frames!`);
|
||||
cb();
|
||||
});
|
||||
};
|
||||
});
|
||||
async.series(jobs, next);
|
||||
});
|
||||
}
|
||||
|
||||
function cleanup (next) {
|
||||
console.log('Cleaning up...');
|
||||
exec(`rm -r "${TMP}"`, (err) => {
|
||||
if (err) console.error(err)
|
||||
if (next) next()
|
||||
})
|
||||
function cleanup(next) {
|
||||
console.log('Cleaning up...');
|
||||
exec(`rm -r "${TMP}"`, (err) => {
|
||||
if (err)
|
||||
console.error(err);
|
||||
if (next)
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
function pad (n) {
|
||||
return ('00000' + n).slice(-5)
|
||||
function pad(n) {
|
||||
return ('00000' + n).slice(-5);
|
||||
}
|
||||
|
||||
var error = function (err) {
|
||||
if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--verbose') !== -1){
|
||||
console.error(err)
|
||||
} else {
|
||||
console.error('Error running program. Run in verbose mode for more info (-v,--verbose)')
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
if (process.argv.indexOf('-v') !== -1 || process.argv.indexOf('--verbose') !== -1) {
|
||||
console.error(err);
|
||||
}
|
||||
else {
|
||||
console.error('Error running program. Run in verbose mode for more info (-v,--verbose)');
|
||||
}
|
||||
process.exit(1);
|
||||
};
|
||||
process.on('uncaughtException', err => {
|
||||
error(err)
|
||||
})
|
||||
|
||||
error(err);
|
||||
});
|
||||
//convert(process.argv[2], process.argv[3])
|
||||
|
||||
//fix for nexe
|
||||
let args = [].concat(process.argv)
|
||||
let args = [].concat(process.argv);
|
||||
if (args[1].indexOf('v2f.js') === -1) {
|
||||
args.reverse()
|
||||
args.push('node')
|
||||
args.reverse()
|
||||
args.reverse();
|
||||
args.push('node');
|
||||
args.reverse();
|
||||
}
|
||||
|
||||
cmd.arguments('<input> <output>')
|
||||
.version('1.1.0')
|
||||
.option('-i, --input <path>', 'Video source to print to film strip, anything that avconv can read')
|
||||
.option('-o, --output <path>', 'Output directory, will print images on A4 standard paper file')
|
||||
.option('-d, --dpi <dpi>', 'DPI output pages')
|
||||
.option('-f, --film <gauge>', 'Choose film gauge: 16mm, super16, 35mm')
|
||||
.option('-v, --verbose', 'Run in verbose mode')
|
||||
.parse(args)
|
||||
|
||||
initialize(cmd)
|
||||
.version('1.1.0')
|
||||
.option('-i, --input <path>', 'Video source to print to film strip, anything that avconv can read')
|
||||
.option('-o, --output <path>', 'Output directory, will render images on specified page size')
|
||||
.option('-d, --dpi <dpi>', 'DPI output pages')
|
||||
.option('-f, --film <gauge>', 'Choose film gauge: 16mm, super16, 35mm')
|
||||
.option('-w, --width <inches>', 'Output page width, in inches. Default 8.5')
|
||||
.option('-l, --length <inches>', 'Output page length, in inches. Default 11')
|
||||
.option('-v, --verbose', 'Run in verbose mode')
|
||||
.parse(args);
|
||||
initialize(cmd);
|
||||
|
|
Loading…
Reference in New Issue