Integrate fi into CLI with ability to do inverted images
This commit is contained in:
parent
1179e80288
commit
69fb063ac0
|
|
@ -64,4 +64,10 @@ interface Message {
|
|||
scale? : number;
|
||||
}
|
||||
|
||||
interface Channels {
|
||||
red : string;
|
||||
green : string;
|
||||
blue: string;
|
||||
}
|
||||
|
||||
declare function humanizeDuration(a : any, b : any) : string;
|
||||
|
|
@ -74,11 +74,30 @@ class CLI {
|
|||
type: String,
|
||||
required: false
|
||||
});
|
||||
parser.add_argument('-w', '--width', {
|
||||
help: 'Width of screen (override .env)',
|
||||
type: 'int',
|
||||
required: false
|
||||
});
|
||||
parser.add_argument('-H', '--height', {
|
||||
help: 'Height of screen (override .env)',
|
||||
type: 'int',
|
||||
required: false
|
||||
});
|
||||
parser.add_argument('-v', '--verbose', {
|
||||
help: 'Enable verbose output',
|
||||
action: 'store_true'
|
||||
});
|
||||
this.args = parser.parse_args();
|
||||
if (this.args.verbose) {
|
||||
console.dir(this.args);
|
||||
}
|
||||
if (typeof this.args.width !== 'undefined') {
|
||||
this.width = this.args.width;
|
||||
}
|
||||
if (typeof this.args.height !== 'undefined') {
|
||||
this.height = this.args.height;
|
||||
}
|
||||
//overwrite defaults
|
||||
}
|
||||
async parse(filePath) {
|
||||
|
|
@ -127,6 +146,7 @@ class CLI {
|
|||
break;
|
||||
case 'I':
|
||||
cmd.action = Actions.INVERT;
|
||||
cmd.time = 1000;
|
||||
break;
|
||||
case 'IRGB':
|
||||
cmd.action = Actions.IRGB;
|
||||
|
|
@ -224,15 +244,51 @@ class CLI {
|
|||
const img = await files_1.Files.getImageObject(cmd.file, stats);
|
||||
const info = await this.ffprobe.info(cmd.file);
|
||||
let dimensions;
|
||||
//console.dir(img);
|
||||
//console.dir(info);
|
||||
let inverted;
|
||||
if (invert) {
|
||||
try {
|
||||
inverted = await this.image.invert(img.path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error inverting image`, err);
|
||||
}
|
||||
img.path = inverted;
|
||||
}
|
||||
this.display.setSource(info.width, info.height);
|
||||
dimensions = this.display.getOutgoingPosition();
|
||||
this.log.info(`Expose: ${img.name}`);
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
await this.camera.open();
|
||||
result = await this.fd.display(img.path, [cmd.time]);
|
||||
await this.camera.close();
|
||||
this.log.info(`${invert ? 'INVERT' : 'EXPOSE'}: [${cmd.time}] ${img.name}`);
|
||||
try {
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error loading image ${img.path} for display`, err);
|
||||
}
|
||||
try {
|
||||
await this.camera.open();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error opening camera`, err);
|
||||
}
|
||||
try {
|
||||
result = await this.fd.display(img.path, [cmd.time]);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error displaying image ${cmd.file}`, err);
|
||||
}
|
||||
try {
|
||||
await this.camera.close();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error closing camera`, err);
|
||||
}
|
||||
if (invert) {
|
||||
try {
|
||||
await (0, promises_1.unlink)(inverted);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error cleaning up inverted image temp file ${inverted}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
async rgb(cmd, invert = false) {
|
||||
const start = Date.now();
|
||||
|
|
@ -245,15 +301,54 @@ class CLI {
|
|||
this.display.setSource(info.width, info.height);
|
||||
dimensions = this.display.getOutgoingPosition();
|
||||
this.log.info(`RGB: ${img.name}`);
|
||||
channels = await this.image.rgb(img.path);
|
||||
//console.dir(channels)
|
||||
await this.fd.load(channels.red, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
await this.camera.open();
|
||||
result = await this.fd.display(channels.red, [cmd.times[0]]);
|
||||
await this.fd.load(channels.green, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
result = await this.fd.display(channels.green, [cmd.times[1]]);
|
||||
await this.fd.load(channels.blue, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
result = await this.fd.display(channels.blue, [cmd.times[2]]);
|
||||
try {
|
||||
channels = await this.image.rgb(img.path, invert);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error getting temp files for channels`, err);
|
||||
}
|
||||
try {
|
||||
await this.fd.load(channels.red, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error loading red channel for display`, err);
|
||||
}
|
||||
try {
|
||||
await this.camera.open();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error opening camera`, err);
|
||||
}
|
||||
try {
|
||||
result = await this.fd.display(channels.red, [cmd.times[0]]);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error displaying red channel`, err);
|
||||
}
|
||||
try {
|
||||
await this.fd.load(channels.green, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error loading green channel`, err);
|
||||
}
|
||||
try {
|
||||
result = await this.fd.display(channels.green, [cmd.times[1]]);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error displaying green channel`, err);
|
||||
}
|
||||
try {
|
||||
await this.fd.load(channels.blue, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error loading blue channel`, err);
|
||||
}
|
||||
try {
|
||||
result = await this.fd.display(channels.blue, [cmd.times[2]]);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error displaying blue channel`, err);
|
||||
}
|
||||
try {
|
||||
await (0, promises_1.unlink)(channels.red);
|
||||
await (0, promises_1.unlink)(channels.green);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,10 +1,12 @@
|
|||
export declare enum fiMode {
|
||||
RGB = 0,
|
||||
IRGB = 1
|
||||
IRGB = 1,
|
||||
INVERT = 2
|
||||
}
|
||||
export declare class FilmoutImage {
|
||||
private log;
|
||||
private bin;
|
||||
constructor(bin: string);
|
||||
rgb(image: string, red: string, green: string, blue: string): Promise<void>;
|
||||
rgb(image: string, red: string, green: string, blue: string, invert?: boolean): Promise<void>;
|
||||
invert(image: string, inverted: string): Promise<void>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,17 +7,18 @@ var fiMode;
|
|||
(function (fiMode) {
|
||||
fiMode[fiMode["RGB"] = 0] = "RGB";
|
||||
fiMode[fiMode["IRGB"] = 1] = "IRGB";
|
||||
fiMode[fiMode["INVERT"] = 2] = "INVERT";
|
||||
})(fiMode || (exports.fiMode = fiMode = {}));
|
||||
class FilmoutImage {
|
||||
constructor(bin) {
|
||||
this.log = (0, log_1.createLog)('fi');
|
||||
this.bin = bin;
|
||||
}
|
||||
async rgb(image, red, green, blue) {
|
||||
async rgb(image, red, green, blue, invert = false) {
|
||||
const cmd = [
|
||||
this.bin,
|
||||
image,
|
||||
'-m', fiMode.RGB,
|
||||
'-m', invert ? fiMode.IRGB : fiMode.RGB,
|
||||
'-r', red,
|
||||
'-g', green,
|
||||
'-b', blue
|
||||
|
|
@ -31,6 +32,22 @@ class FilmoutImage {
|
|||
this.log.error(`Error executing ${cmd.join(' ')}`, err);
|
||||
}
|
||||
}
|
||||
async invert(image, inverted) {
|
||||
const cmd = [
|
||||
this.bin,
|
||||
image,
|
||||
'-m', fiMode.INVERT,
|
||||
'-i', inverted
|
||||
];
|
||||
this.log.info(`'Executing: ${cmd.join(' ')}`);
|
||||
const shell = new shell_1.Shell(cmd, null, function (stdio) { console.log(stdio); }, null, null, true);
|
||||
try {
|
||||
await shell.execute();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error executing ${cmd.join(' ')}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.FilmoutImage = FilmoutImage;
|
||||
module.exports = { FilmoutImage };
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fi/index.ts"],"names":[],"mappings":";;;AACA,gCAAkC;AAClC,oCAAiC;AAEjC,IAAY,MAGX;AAHD,WAAY,MAAM;IACjB,iCAAO,CAAA;IACP,mCAAQ,CAAA;AACT,CAAC,EAHW,MAAM,sBAAN,MAAM,QAGjB;AAED,MAAa,YAAY;IAIxB,YAAa,GAAY;QACxB,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,KAAc,EAAE,GAAY,EAAE,KAAc,EAAE,IAAa;QAC5E,MAAM,GAAG,GAAW;YACnB,IAAI,CAAC,GAAG;YACR,KAAK;YACL,IAAI,EAAE,MAAM,CAAC,GAAG;YAChB,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;SACV,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAW,IAAI,aAAK,CAAC,GAAG,EAAE,IAAI,EAAE,UAAS,KAAc,IAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAE9G,IAAI,CAAC;YACJ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;CACD;AA3BD,oCA2BC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,YAAY,EAAE,CAAC"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/fi/index.ts"],"names":[],"mappings":";;;AACA,gCAAkC;AAClC,oCAAiC;AAEjC,IAAY,MAIX;AAJD,WAAY,MAAM;IACjB,iCAAO,CAAA;IACP,mCAAQ,CAAA;IACR,uCAAU,CAAA;AACX,CAAC,EAJW,MAAM,sBAAN,MAAM,QAIjB;AAED,MAAa,YAAY;IAIxB,YAAa,GAAY;QACxB,IAAI,CAAC,GAAG,GAAG,IAAA,eAAS,EAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IAChB,CAAC;IAEM,KAAK,CAAC,GAAG,CAAE,KAAc,EAAE,GAAY,EAAE,KAAc,EAAE,IAAa,EAAE,SAAmB,KAAK;QACtG,MAAM,GAAG,GAAW;YACnB,IAAI,CAAC,GAAG;YACR,KAAK;YACL,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG;YACvC,IAAI,EAAE,GAAG;YACT,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;SACV,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAW,IAAI,aAAK,CAAC,GAAG,EAAE,IAAI,EAAE,UAAS,KAAc,IAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAE9G,IAAI,CAAC;YACJ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,KAAc,EAAE,QAAiB;QACrD,MAAM,GAAG,GAAW;YACnB,IAAI,CAAC,GAAG;YACR,KAAK;YACL,IAAI,EAAE,MAAM,CAAC,MAAM;YACnB,IAAI,EAAE,QAAQ;SACd,CAAC;QACF,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAW,IAAI,aAAK,CAAC,GAAG,EAAE,IAAI,EAAE,UAAS,KAAc,IAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;QAE9G,IAAI,CAAC;YACJ,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;CACD;AA5CD,oCA4CC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,YAAY,EAAE,CAAC"}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
/// <reference types="node" />
|
||||
export declare class Image {
|
||||
private prefix;
|
||||
private thumbnailCache;
|
||||
private thumbnailHash;
|
||||
private colorCache;
|
||||
|
|
@ -8,11 +7,11 @@ export declare class Image {
|
|||
private tmp;
|
||||
private fi;
|
||||
constructor(fiBin: string);
|
||||
private mktemp;
|
||||
private dpx2png;
|
||||
thumbnail(path: string, width: number, height: number): Promise<Buffer>;
|
||||
private color;
|
||||
blank(width: number, height: number): Promise<Buffer>;
|
||||
gray(width: number, height: number): Promise<Buffer>;
|
||||
rgb(image: string): Promise<any>;
|
||||
invert(image: string): Promise<string>;
|
||||
rgb(image: string, invert?: boolean): Promise<Channels>;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,34 +7,19 @@ exports.Image = void 0;
|
|||
const sharp_1 = __importDefault(require("sharp"));
|
||||
const hash_1 = require("../hash");
|
||||
const path_1 = require("path");
|
||||
const os_1 = require("os");
|
||||
const promises_1 = require("fs/promises");
|
||||
const shell_1 = require("../shell");
|
||||
const fi_1 = require("../fi");
|
||||
const tmp_1 = require("../tmp");
|
||||
class Image {
|
||||
constructor(fiBin) {
|
||||
this.prefix = 'fm_thumbs';
|
||||
this.thumbnailCache = null;
|
||||
this.thumbnailHash = null;
|
||||
this.colorCache = null;
|
||||
this.colorHash = null;
|
||||
this.tmp = null;
|
||||
if (this.tmp === null) {
|
||||
this.tmp = (0, os_1.tmpdir)();
|
||||
}
|
||||
this.tmp = new tmp_1.TMP('fm_images');
|
||||
this.fi = new fi_1.FilmoutImage(fiBin);
|
||||
}
|
||||
async mktemp(ext = '.png') {
|
||||
const randomString = Math.random().toString(36).slice(2);
|
||||
const tempPath = (0, path_1.join)(this.tmp, this.prefix, randomString + `.${ext}`);
|
||||
try {
|
||||
await (0, promises_1.mkdir)((0, path_1.join)(this.tmp, this.prefix));
|
||||
}
|
||||
catch (err) {
|
||||
//
|
||||
}
|
||||
return tempPath;
|
||||
}
|
||||
async dpx2png(input, output) {
|
||||
let dpx = null;
|
||||
const args = [
|
||||
|
|
@ -58,7 +43,7 @@ class Image {
|
|||
if (hash !== this.thumbnailHash) {
|
||||
if ((0, path_1.extname)(path).toLowerCase() === '.dpx') {
|
||||
try {
|
||||
newPath = await this.mktemp('png');
|
||||
newPath = await this.tmp.mktemp('png');
|
||||
await this.dpx2png(path, newPath);
|
||||
path = newPath;
|
||||
}
|
||||
|
|
@ -104,14 +89,38 @@ class Image {
|
|||
return this.color(width, height, 0, 0, 0);
|
||||
}
|
||||
async gray(width, height) {
|
||||
return this.color(width, height, 125, 125, 125);
|
||||
return this.color(width, height, 127, 127, 127);
|
||||
}
|
||||
async rgb(image) {
|
||||
const red = await this.mktemp('tif');
|
||||
const green = await this.mktemp('tif');
|
||||
const blue = await this.mktemp('tif');
|
||||
async invert(image) {
|
||||
let inverted;
|
||||
try {
|
||||
await this.fi.rgb(image, red, green, blue);
|
||||
inverted = await this.tmp.mktemp('.tif');
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
try {
|
||||
await this.fi.invert(image, inverted);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
return inverted;
|
||||
}
|
||||
async rgb(image, invert = false) {
|
||||
let red;
|
||||
let green;
|
||||
let blue;
|
||||
try {
|
||||
red = await this.tmp.mktemp('tif');
|
||||
green = await this.tmp.mktemp('tif');
|
||||
blue = await this.tmp.mktemp('tif');
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
}
|
||||
try {
|
||||
await this.fi.rgb(image, red, green, blue, invert);
|
||||
}
|
||||
catch (err) {
|
||||
throw err;
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":"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"}
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/image/index.ts"],"names":[],"mappings":"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"}
|
||||
|
|
@ -136,7 +136,12 @@ class Sequence {
|
|||
this.current = seq;
|
||||
this.frame = 0;
|
||||
this.progress = 0;
|
||||
await this.enumerate();
|
||||
try {
|
||||
await this.enumerate();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error enumerating images`, err);
|
||||
}
|
||||
this.updateClientsOnLoad();
|
||||
}
|
||||
updateClientsOnLoad() {
|
||||
|
|
@ -170,7 +175,12 @@ class Sequence {
|
|||
this.frames = this.images.length;
|
||||
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
||||
if (this.frames > 0) {
|
||||
this.info = await this.ffprobe.info(this.images[0].path);
|
||||
try {
|
||||
this.info = await this.ffprobe.info(this.images[0].path);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error getting info about image`, err);
|
||||
}
|
||||
}
|
||||
if (this.info !== null) {
|
||||
screen = this.display.getScreen();
|
||||
|
|
@ -383,14 +393,34 @@ class Sequence {
|
|||
const img = this.images[this.frame];
|
||||
const dimensions = this.display.getOutgoingPosition();
|
||||
this.log.info(`Frame: ${this.frame} / ${this.images.length}`);
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
try {
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error loading image ${img.path}`, err);
|
||||
}
|
||||
load = Date.now() - start;
|
||||
await this.camera.open();
|
||||
try {
|
||||
await this.camera.open();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error opening camera`, err);
|
||||
}
|
||||
open = Date.now() - start - load;
|
||||
result = await this.fd.display(img.path, [this.exposure]);
|
||||
try {
|
||||
result = await this.fd.display(img.path, [this.exposure]);
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error displaying image`, err);
|
||||
}
|
||||
exposureReported = result.reported;
|
||||
exposureElapsed = Date.now() - start - load - open;
|
||||
await this.camera.close();
|
||||
try {
|
||||
await this.camera.close();
|
||||
}
|
||||
catch (err) {
|
||||
this.log.error(`Error closing camera`, err);
|
||||
}
|
||||
close = Date.now() - start - load - open - exposureElapsed;
|
||||
total = Date.now() - start;
|
||||
this.stats.add(load, open, exposureElapsed, exposureReported, close, total);
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -0,0 +1,6 @@
|
|||
export declare class TMP {
|
||||
private tmp;
|
||||
private prefix;
|
||||
constructor(prefix?: string, tmp?: string);
|
||||
mktemp(ext?: string): Promise<string>;
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TMP = void 0;
|
||||
const path_1 = require("path");
|
||||
const promises_1 = require("fs/promises");
|
||||
const os_1 = require("os");
|
||||
class TMP {
|
||||
constructor(prefix = 'tmp', tmp = null) {
|
||||
this.prefix = prefix;
|
||||
this.tmp = tmp === null ? (0, os_1.tmpdir)() : tmp;
|
||||
}
|
||||
async mktemp(ext = '.png') {
|
||||
const randomString = Math.random().toString(36).slice(2);
|
||||
const tempPath = (0, path_1.join)(this.tmp, this.prefix, String(Date.now()) + '-' + randomString + `.${ext}`);
|
||||
try {
|
||||
await (0, promises_1.mkdir)((0, path_1.join)(this.tmp, this.prefix));
|
||||
}
|
||||
catch (err) {
|
||||
//
|
||||
}
|
||||
return tempPath;
|
||||
}
|
||||
}
|
||||
exports.TMP = TMP;
|
||||
module.exports = { TMP };
|
||||
//# sourceMappingURL=index.js.map
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tmp/index.ts"],"names":[],"mappings":";;;AAAA,+BAAqC;AACrC,0CAAoC;AACpC,2BAA4B;AAE5B,MAAa,GAAG;IAIf,YAAa,SAAkB,KAAK,EAAE,MAAe,IAAI;QACxD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,GAAG,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,IAAA,WAAM,GAAE,CAAC,CAAC,CAAC,GAAG,CAAC;IAC1C,CAAC;IAEM,KAAK,CAAC,MAAM,CAAE,MAAe,MAAM;QACzC,MAAM,YAAY,GAAY,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAClE,MAAM,QAAQ,GAAY,IAAA,WAAI,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,GAAG,GAAG,GAAG,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC,CAAC;QAE3G,IAAI,CAAC;YACJ,MAAM,IAAA,gBAAK,EAAC,IAAA,WAAI,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,EAAE;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD;AArBD,kBAqBC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,GAAG,EAAE,CAAC"}
|
||||
130
src/cli/index.ts
130
src/cli/index.ts
|
|
@ -35,9 +35,13 @@ enum Actions {
|
|||
|
||||
interface Args {
|
||||
input? : string;
|
||||
command? : string;
|
||||
width? : number;
|
||||
height? : number;
|
||||
mock?: boolean;
|
||||
focus? : boolean;
|
||||
framing? : boolean;
|
||||
verbose? : boolean;
|
||||
}
|
||||
|
||||
interface CMD {
|
||||
|
|
@ -121,14 +125,37 @@ export class CLI {
|
|||
type: String,
|
||||
required: false
|
||||
});
|
||||
|
||||
parser.add_argument('-w', '--width', {
|
||||
help: 'Width of screen (override .env)',
|
||||
type: 'int',
|
||||
required: false
|
||||
});
|
||||
|
||||
parser.add_argument('-H', '--height', {
|
||||
help: 'Height of screen (override .env)',
|
||||
type: 'int',
|
||||
required: false
|
||||
});
|
||||
|
||||
parser.add_argument('-v', '--verbose', {
|
||||
help: 'Enable verbose output',
|
||||
action: 'store_true'
|
||||
});
|
||||
|
||||
this.args = parser.parse_args();
|
||||
this.args = parser.parse_args() as Args;
|
||||
|
||||
if (this.args.verbose) {
|
||||
console.dir(this.args);
|
||||
}
|
||||
|
||||
if (typeof this.args.width !== 'undefined') {
|
||||
this.width = this.args.width;
|
||||
}
|
||||
|
||||
if (typeof this.args.height !== 'undefined') {
|
||||
this.height = this.args.height;
|
||||
}
|
||||
//overwrite defaults
|
||||
}
|
||||
|
||||
|
|
@ -184,6 +211,7 @@ export class CLI {
|
|||
break;
|
||||
case 'I' :
|
||||
cmd.action = Actions.INVERT;
|
||||
cmd.time = 1000;
|
||||
break;
|
||||
case 'IRGB' :
|
||||
cmd.action = Actions.IRGB;
|
||||
|
|
@ -277,29 +305,61 @@ export class CLI {
|
|||
const img : ImageObject = await Files.getImageObject(cmd.file, stats);
|
||||
const info : VideoInfo = await this.ffprobe.info(cmd.file);
|
||||
let dimensions : fdOutgoingPosition;
|
||||
let inverted : string;
|
||||
|
||||
//console.dir(img);
|
||||
//console.dir(info);
|
||||
if (invert) {
|
||||
try {
|
||||
inverted = await this.image.invert(img.path);
|
||||
} catch (err) {
|
||||
this.log.error(`Error inverting image`, err);
|
||||
}
|
||||
|
||||
img.path = inverted;
|
||||
}
|
||||
|
||||
this.display.setSource(info.width, info.height);
|
||||
|
||||
dimensions = this.display.getOutgoingPosition();
|
||||
|
||||
this.log.info(`Expose: ${img.name}`);
|
||||
this.log.info(`${invert ? 'INVERT' : 'EXPOSE'}: [${cmd.time}] ${img.name}`);
|
||||
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
try {
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
} catch (err) {
|
||||
this.log.error(`Error loading image ${img.path} for display`, err);
|
||||
}
|
||||
|
||||
await this.camera.open();
|
||||
try {
|
||||
await this.camera.open();
|
||||
} catch (err) {
|
||||
this.log.error(`Error opening camera`, err);
|
||||
}
|
||||
|
||||
result = await this.fd.display(img.path, [ cmd.time ] );
|
||||
try {
|
||||
result = await this.fd.display(img.path, [ cmd.time ] );
|
||||
} catch (err) {
|
||||
this.log.error(`Error displaying image ${cmd.file}`, err);
|
||||
}
|
||||
|
||||
await this.camera.close();
|
||||
try {
|
||||
await this.camera.close();
|
||||
} catch (err) {
|
||||
this.log.error(`Error closing camera`, err);
|
||||
}
|
||||
|
||||
if (invert) {
|
||||
try {
|
||||
await unlink(inverted);
|
||||
} catch (err) {
|
||||
this.log.error(`Error cleaning up inverted image temp file ${inverted}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async rgb (cmd : CMD, invert : boolean = false) {
|
||||
const start : number = Date.now();
|
||||
let result : fdResult;
|
||||
let channels : any;
|
||||
let channels : Channels;
|
||||
|
||||
const stats : Stats = await lstat(cmd.file);
|
||||
const img : ImageObject = await Files.getImageObject(cmd.file, stats);
|
||||
|
|
@ -312,17 +372,53 @@ export class CLI {
|
|||
|
||||
this.log.info(`RGB: ${img.name}`);
|
||||
|
||||
channels = await this.image.rgb(img.path);
|
||||
await this.fd.load(channels.red, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
await this.camera.open();
|
||||
try {
|
||||
channels = await this.image.rgb(img.path, invert);
|
||||
} catch (err) {
|
||||
this.log.error(`Error getting temp files for channels`, err);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.fd.load(channels.red, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
} catch (err) {
|
||||
this.log.error(`Error loading red channel for display`, err);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.camera.open();
|
||||
} catch (err) {
|
||||
this.log.error(`Error opening camera`, err);
|
||||
}
|
||||
|
||||
result = await this.fd.display(channels.red, [ cmd.times[0] ] );
|
||||
try {
|
||||
result = await this.fd.display(channels.red, [ cmd.times[0] ] );
|
||||
} catch (err) {
|
||||
this.log.error(`Error displaying red channel`, err);
|
||||
}
|
||||
|
||||
await this.fd.load(channels.green, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
result = await this.fd.display(channels.green, [ cmd.times[1] ] );
|
||||
try {
|
||||
await this.fd.load(channels.green, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
} catch (err) {
|
||||
this.log.error(`Error loading green channel`, err);
|
||||
}
|
||||
|
||||
await this.fd.load(channels.blue, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
result = await this.fd.display(channels.blue, [ cmd.times[2] ] );
|
||||
try {
|
||||
result = await this.fd.display(channels.green, [ cmd.times[1] ] );
|
||||
} catch (err) {
|
||||
this.log.error(`Error displaying green channel`, err);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.fd.load(channels.blue, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
} catch (err) {
|
||||
this.log.error(`Error loading blue channel`, err);
|
||||
}
|
||||
|
||||
try {
|
||||
result = await this.fd.display(channels.blue, [ cmd.times[2] ] );
|
||||
} catch (err) {
|
||||
this.log.error(`Error displaying blue channel`, err);
|
||||
}
|
||||
|
||||
try {
|
||||
await unlink(channels.red);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import { Shell } from '../shell';
|
|||
|
||||
export enum fiMode {
|
||||
RGB = 0,
|
||||
IRGB = 1
|
||||
IRGB = 1,
|
||||
INVERT = 2
|
||||
}
|
||||
|
||||
export class FilmoutImage {
|
||||
|
|
@ -16,11 +17,11 @@ export class FilmoutImage {
|
|||
this.bin = bin;
|
||||
}
|
||||
|
||||
public async rgb (image : string, red : string, green : string, blue : string) {
|
||||
public async rgb (image : string, red : string, green : string, blue : string, invert : boolean = false) {
|
||||
const cmd : any[] = [
|
||||
this.bin,
|
||||
image,
|
||||
'-m', fiMode.RGB,
|
||||
'-m', invert ? fiMode.IRGB : fiMode.RGB,
|
||||
'-r', red,
|
||||
'-g', green,
|
||||
'-b', blue
|
||||
|
|
@ -34,6 +35,23 @@ export class FilmoutImage {
|
|||
this.log.error(`Error executing ${cmd.join(' ')}`, err);
|
||||
}
|
||||
}
|
||||
|
||||
public async invert (image : string, inverted : string) {
|
||||
const cmd : any[] = [
|
||||
this.bin,
|
||||
image,
|
||||
'-m', fiMode.INVERT,
|
||||
'-i', inverted
|
||||
];
|
||||
this.log.info(`'Executing: ${cmd.join(' ')}`);
|
||||
const shell : Shell = new Shell(cmd, null, function(stdio : string){ console.log(stdio); }, null, null, true);
|
||||
|
||||
try {
|
||||
await shell.execute();
|
||||
} catch (err) {
|
||||
this.log.error(`Error executing ${cmd.join(' ')}`, err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { FilmoutImage };
|
||||
|
|
@ -64,4 +64,10 @@ interface Message {
|
|||
scale? : number;
|
||||
}
|
||||
|
||||
interface Channels {
|
||||
red : string;
|
||||
green : string;
|
||||
blue: string;
|
||||
}
|
||||
|
||||
declare function humanizeDuration(a : any, b : any) : string;
|
||||
|
|
@ -2,40 +2,25 @@ import sharp from 'sharp';
|
|||
import type { SharpOptions, ResizeOptions } from 'sharp';
|
||||
import { Hashes } from '../hash';
|
||||
import { join, extname } from 'path';
|
||||
import { tmpdir } from 'os';
|
||||
import { mkdir, unlink } from 'fs/promises';
|
||||
import { unlink } from 'fs/promises';
|
||||
import { Shell } from '../shell';
|
||||
import { FilmoutImage } from '../fi';
|
||||
import type { fiMode } from '../fi';
|
||||
import { TMP } from '../tmp';
|
||||
|
||||
export class Image {
|
||||
private prefix : string = 'fm_thumbs';
|
||||
private thumbnailCache : Buffer = null;
|
||||
private thumbnailHash : string = null;
|
||||
private colorCache : Buffer = null;
|
||||
private colorHash : string = null;
|
||||
private tmp : string = null;
|
||||
private tmp : TMP;
|
||||
private fi : FilmoutImage;
|
||||
|
||||
constructor (fiBin : string) {
|
||||
if (this.tmp === null) {
|
||||
this.tmp = tmpdir();
|
||||
}
|
||||
this.tmp = new TMP('fm_images');
|
||||
this.fi = new FilmoutImage(fiBin);
|
||||
}
|
||||
|
||||
private async mktemp (ext : string = '.png') : Promise<string> {
|
||||
const randomString : string = Math.random().toString(36).slice(2);
|
||||
const tempPath : string = join(this.tmp, this.prefix, randomString + `.${ext}`);
|
||||
|
||||
try {
|
||||
await mkdir(join(this.tmp, this.prefix));
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
return tempPath;
|
||||
}
|
||||
|
||||
private async dpx2png (input : string, output : string) {
|
||||
let dpx : any = null;
|
||||
const args : string[] = [
|
||||
|
|
@ -59,7 +44,7 @@ export class Image {
|
|||
if (hash !== this.thumbnailHash) {
|
||||
if (extname(path).toLowerCase() === '.dpx') {
|
||||
try {
|
||||
newPath = await this.mktemp('png');
|
||||
newPath = await this.tmp.mktemp('png');
|
||||
await this.dpx2png(path, newPath);
|
||||
path = newPath;
|
||||
} catch (err) {
|
||||
|
|
@ -106,16 +91,42 @@ export class Image {
|
|||
}
|
||||
|
||||
public async gray (width : number, height : number) {
|
||||
return this.color(width, height, 125, 125, 125);
|
||||
return this.color(width, height, 127, 127, 127);
|
||||
}
|
||||
|
||||
public async rgb (image : string) : Promise<any> {
|
||||
const red : string = await this.mktemp('tif');
|
||||
const green : string = await this.mktemp('tif');
|
||||
const blue : string = await this.mktemp('tif');
|
||||
public async invert (image : string) : Promise<string> {
|
||||
let inverted : string;
|
||||
|
||||
try {
|
||||
await this.fi.rgb(image, red, green, blue);
|
||||
inverted = await this.tmp.mktemp('.tif');
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.fi.invert(image, inverted);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
return inverted;
|
||||
}
|
||||
|
||||
public async rgb (image : string, invert : boolean = false) : Promise<Channels> {
|
||||
let red : string;
|
||||
let green : string;
|
||||
let blue : string;
|
||||
|
||||
try {
|
||||
red = await this.tmp.mktemp('tif');
|
||||
green = await this.tmp.mktemp('tif');
|
||||
blue = await this.tmp.mktemp('tif');
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.fi.rgb(image, red, green, blue, invert);
|
||||
} catch (err) {
|
||||
throw err;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -164,11 +164,13 @@ export class Sequence {
|
|||
if (!this.running) {
|
||||
break;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.frameRecord();
|
||||
} catch (err) {
|
||||
this.log.error(`Error recording frame`, err);
|
||||
}
|
||||
|
||||
this.frameAdvance();
|
||||
}
|
||||
//complete running
|
||||
|
|
@ -180,7 +182,13 @@ export class Sequence {
|
|||
this.current = seq;
|
||||
this.frame = 0;
|
||||
this.progress = 0;
|
||||
await this.enumerate();
|
||||
|
||||
try {
|
||||
await this.enumerate();
|
||||
} catch (err) {
|
||||
this.log.error(`Error enumerating images`, err);
|
||||
}
|
||||
|
||||
this.updateClientsOnLoad();
|
||||
}
|
||||
|
||||
|
|
@ -222,7 +230,11 @@ export class Sequence {
|
|||
this.log.info(`Sequence ${this.current.name} contains ${this.images.length} image${this.images.length === 1 ? '' : 's'}`);
|
||||
|
||||
if (this.frames > 0) {
|
||||
this.info = await this.ffprobe.info(this.images[0].path);
|
||||
try {
|
||||
this.info = await this.ffprobe.info(this.images[0].path);
|
||||
} catch (err) {
|
||||
this.log.error(`Error getting info about image`, err);
|
||||
}
|
||||
}
|
||||
if (this.info !== null) {
|
||||
screen = this.display.getScreen();
|
||||
|
|
@ -446,15 +458,40 @@ export class Sequence {
|
|||
let result : fdResult;
|
||||
const img : ImageObject = this.images[this.frame];
|
||||
const dimensions : fdOutgoingPosition = this.display.getOutgoingPosition();
|
||||
|
||||
this.log.info(`Frame: ${this.frame} / ${this.images.length}`);
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
|
||||
try {
|
||||
await this.fd.load(img.path, dimensions.x, dimensions.y, dimensions.w, dimensions.h);
|
||||
} catch (err) {
|
||||
this.log.error(`Error loading image ${img.path}`, err);
|
||||
}
|
||||
|
||||
load = Date.now() - start;
|
||||
await this.camera.open();
|
||||
|
||||
try {
|
||||
await this.camera.open();
|
||||
} catch (err) {
|
||||
this.log.error(`Error opening camera`, err);
|
||||
}
|
||||
|
||||
open = Date.now() - start - load;
|
||||
result = await this.fd.display(img.path, [ this.exposure ] );
|
||||
|
||||
try {
|
||||
result = await this.fd.display(img.path, [ this.exposure ] );
|
||||
} catch (err) {
|
||||
this.log.error(`Error displaying image`, err);
|
||||
}
|
||||
|
||||
exposureReported = result.reported;
|
||||
exposureElapsed = Date.now() - start - load - open;
|
||||
await this.camera.close();
|
||||
|
||||
try {
|
||||
await this.camera.close();
|
||||
} catch (err) {
|
||||
this.log.error(`Error closing camera`, err);
|
||||
}
|
||||
|
||||
close = Date.now() - start - load - open - exposureElapsed;
|
||||
total = Date.now() - start;
|
||||
this.stats.add(load, open, exposureElapsed, exposureReported, close, total);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
import { join, extname } from 'path';
|
||||
import { mkdir } from 'fs/promises';
|
||||
import { tmpdir } from 'os';
|
||||
|
||||
export class TMP {
|
||||
private tmp : string;
|
||||
private prefix : string;
|
||||
|
||||
constructor (prefix : string = 'tmp', tmp : string = null) {
|
||||
this.prefix = prefix;
|
||||
this.tmp = tmp === null ? tmpdir() : tmp;
|
||||
}
|
||||
|
||||
public async mktemp (ext : string = '.png') : Promise<string> {
|
||||
const randomString : string = Math.random().toString(36).slice(2);
|
||||
const tempPath : string = join(this.tmp, this.prefix, String(Date.now()) + '-' + randomString + `.${ext}`);
|
||||
|
||||
try {
|
||||
await mkdir(join(this.tmp, this.prefix));
|
||||
} catch (err) {
|
||||
//
|
||||
}
|
||||
|
||||
return tempPath;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { TMP };
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
E,test/grayscale_43.jpg,2500
|
||||
E,test/grayscale_43.jpg,2000
|
||||
I,test/grayscale_43.jpg,1500
|
||||
E,test/grayscale_43.jpg,1000
|
||||
RGB,test/grayscale_43.jpg,200,400,600
|
||||
RGB,test/grayscale_43.jpg,1000,2000,3000
|
||||
IRGB,test/grayscale_43.jpg,3000,2000,1000
|
||||
|
|
|
|||
Loading…
Reference in New Issue