Integrate fi into CLI with ability to do inverted images

This commit is contained in:
Matt McWilliams 2026-03-01 13:50:13 -05:00
parent 1179e80288
commit 69fb063ac0
21 changed files with 500 additions and 111 deletions

View File

@ -64,4 +64,10 @@ interface Message {
scale? : number;
}
interface Channels {
red : string;
green : string;
blue: string;
}
declare function humanizeDuration(a : any, b : any) : string;

127
dist/cli/index.js vendored
View File

@ -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

6
dist/fi/index.d.ts vendored
View File

@ -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>;
}

21
dist/fi/index.js vendored
View File

@ -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 };

View File

@ -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"}

View File

@ -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>;
}

57
dist/image/index.js vendored
View File

@ -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;

View File

@ -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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"}

View File

@ -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

6
dist/tmp/index.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
export declare class TMP {
private tmp;
private prefix;
constructor(prefix?: string, tmp?: string);
mktemp(ext?: string): Promise<string>;
}

26
dist/tmp/index.js vendored Normal file
View File

@ -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

1
dist/tmp/index.js.map vendored Normal file
View File

@ -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"}

View File

@ -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);

View File

@ -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 };

6
src/globals.d.ts vendored
View File

@ -64,4 +64,10 @@ interface Message {
scale? : number;
}
interface Channels {
red : string;
green : string;
blue: string;
}
declare function humanizeDuration(a : any, b : any) : string;

View File

@ -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;
}

View File

@ -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);

28
src/tmp/index.ts Normal file
View File

@ -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 };

View File

@ -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