Add framing feature. Also only works correctly when sequence is selected but that's okay for now. Resolves #2

This commit is contained in:
Matt McWilliams 2024-10-24 11:23:33 -04:00
parent b231f8cd48
commit db10d318f5
11 changed files with 193 additions and 14 deletions

View File

@ -14,6 +14,7 @@ class Display {
private screen : any; private screen : any;
private sequence : boolean = false; private sequence : boolean = false;
private focus : boolean = false; private focus : boolean = false;
private framing : boolean = false;
private offsetX : number = 0; private offsetX : number = 0;
private offsetY : number = 0; private offsetY : number = 0;
@ -90,7 +91,7 @@ class Display {
} }
public updateDisplay () { public updateDisplay () {
if (!this.sequence && !this.focus) { if (!this.sequence && !this.focus && !this.framing) {
return; return;
} }
//console.log(this.sequence); //console.log(this.sequence);
@ -137,6 +138,14 @@ class Display {
this.focus = false; this.focus = false;
} }
public setFraming () {
this.framing= true;
}
public unsetFraming () {
this.framing = false;
}
private onResize (event : any) { private onResize (event : any) {
this.updateSize(); this.updateSize();
this.clear(); this.clear();
@ -337,6 +346,13 @@ class Client {
break; break;
case 'unfocus' : case 'unfocus' :
this.receiveUnfocus(msg); this.receiveUnfocus(msg);
break;
case 'framing' :
this.receiveFraming(msg);
break;
case 'unframing' :
this.receiveUnframing(msg);
break;
case 'display' : case 'display' :
this.receiveDisplay(msg); this.receiveDisplay(msg);
break; break;
@ -481,6 +497,22 @@ class Client {
this.display.updateImage(); this.display.updateImage();
} }
public sendFraming () {
console.log('send framing');
//this.disableClass('manualCtrl');
this.client.send(JSON.stringify({ cmd : 'framing' }));
}
private receiveFraming (msg : Message) {
this.display.setFraming();
this.display.updateImage();
}
private receiveUnframing (msg : Message) {
this.display.unsetFraming();
this.display.updateImage();
}
public sendOffset (x : number, y : number) { public sendOffset (x : number, y : number) {
this.client.send(JSON.stringify({ cmd : 'offset', x, y })); this.client.send(JSON.stringify({ cmd : 'offset', x, y }));
} }

62
dist/index.js vendored
View File

@ -56,6 +56,7 @@ let camera;
let sequence; let sequence;
let index; let index;
let focusImage = null; let focusImage = null;
let framingImage = null;
let port; let port;
let wsPort; let wsPort;
let sequences; let sequences;
@ -218,7 +219,7 @@ async function cmd(msg) {
await select(msg.state.sequence.hash); await select(msg.state.sequence.hash);
break; break;
case 'start': case 'start':
start(); await start();
break; break;
case 'stop': case 'stop':
stop(); stop();
@ -238,6 +239,9 @@ async function cmd(msg) {
case 'focus': case 'focus':
await focus(); await focus();
break; break;
case 'framing':
await framing();
break;
case 'offset': case 'offset':
offset(msg); offset(msg);
break; break;
@ -287,9 +291,12 @@ async function select(id) {
await sequence.load(seq); await sequence.load(seq);
return true; return true;
} }
function start() { async function start() {
if (focus !== null) { if (focusImage !== null) {
stopFocus(); await stopFocus();
}
if (framingImage !== null) {
await stopFraming();
} }
sequence.start(); sequence.start();
} }
@ -342,6 +349,43 @@ async function stopFocus() {
await fd.stop(focusImage); await fd.stop(focusImage);
send({ cmd: 'unfocus' }); send({ cmd: 'unfocus' });
} }
async function framing() {
let pos;
let dims;
let state;
let filePath;
if (framingImage !== null) {
await stopFraming();
return;
}
if (sequence.isLoaded()) {
state = sequence.getState();
pos = {
w: state.display.width,
h: state.display.height,
x: state.offset.x,
y: state.offset.y
};
}
else {
dims = display.getScreen();
pos = {
w: dims.width,
h: dims.height,
x: 0,
y: 0
};
}
framingImage = await testimage_1.TestImage.Frame(pos.w, pos.h);
await fd.load(framingImage, pos.x, pos.y, pos.w, pos.h);
await fd.display(framingImage);
send({ cmd: 'framing' });
}
async function stopFraming() {
framingImage = null;
await fd.stop(framingImage);
send({ cmd: 'unframing' });
}
function offset(msg) { function offset(msg) {
let current = sequence.getCurrent(); let current = sequence.getCurrent();
if (current !== null) { if (current !== null) {
@ -381,6 +425,16 @@ app.get('/:width/:height/image.jpg', async (req, res, next) => {
return next(new Error('Error getting thumbnail')); return next(new Error('Error getting thumbnail'));
} }
} }
else if (framingImage !== null) {
try {
data = await image.thumbnail(framingImage, width, height);
log.info(`Image: ${current.path} - ${width},${height}`);
}
catch (err) {
log.error(`Error getting thumbnail of ${current}`, err);
return next(new Error('Error getting thumbnail'));
}
}
else if (current !== null) { else if (current !== null) {
try { try {
data = await image.thumbnail(current.path, width, height); data = await image.thumbnail(current.path, width, height);

2
dist/index.js.map vendored

File diff suppressed because one or more lines are too long

View File

@ -35,6 +35,8 @@ class TestImage {
const filePath = (0, path_1.join)((0, os_1.tmpdir)(), `frame-${id}.png`); const filePath = (0, path_1.join)((0, os_1.tmpdir)(), `frame-${id}.png`);
const img = PImage.make(width, height); const img = PImage.make(width, height);
const ctx = img.getContext('2d'); const ctx = img.getContext('2d');
const halfW = Math.round(width / 2) - (edge > 1 ? Math.round(edge / 2) : 0);
const halfH = Math.round(height / 2) - (edge > 1 ? Math.round(edge / 2) : 0);
ctx.fillStyle = 'black'; ctx.fillStyle = 'black';
ctx.fillRect(0, 0, width, height); ctx.fillRect(0, 0, width, height);
ctx.fillStyle = 'red'; ctx.fillStyle = 'red';
@ -42,6 +44,8 @@ class TestImage {
ctx.fillRect(0, 0, edge, height); ctx.fillRect(0, 0, edge, height);
ctx.fillRect(0, height - edge, width, edge); ctx.fillRect(0, height - edge, width, edge);
ctx.fillRect(width - edge, 0, edge, height); ctx.fillRect(width - edge, 0, edge, height);
ctx.fillRect(halfW, 0, edge, height);
ctx.fillRect(0, halfH, width, edge);
try { try {
await PImage.encodePNGToStream(img, (0, fs_1.createWriteStream)(filePath)); await PImage.encodePNGToStream(img, (0, fs_1.createWriteStream)(filePath));
} }

View File

@ -1 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testimage/index.ts"],"names":[],"mappings":"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"} {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/testimage/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,kDAAoC;AACpC,2BAAuC;AACvC,2BAA4B;AAC5B,+BAA4B;AAC5B,+BAAkC;AAElC,MAAa,SAAS;IACd,MAAM,CAAC,KAAK,CAAC,KAAK,CAAE,KAAa,EAAE,MAAc,EAAE,OAAgB,CAAC;QAC1E,MAAM,EAAE,GAAY,IAAA,SAAI,GAAE,CAAC;QAC3B,MAAM,QAAQ,GAAY,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,GAAG,GAAoB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAClD,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACrF,MAAM,KAAK,GAAY,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;QACxB,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;QAClC,GAAG,CAAC,SAAS,GAAG,KAAK,CAAC;QACtB,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAChC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACjC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5C,GAAG,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAC5C,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QACrC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACpC,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAA,sBAAiB,EAAC,QAAQ,CAAC,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;QACX,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,KAAK,CAAE,KAAc,EAAE,MAAe,EAAE,QAAiB,EAAE;QAC9E,MAAM,EAAE,GAAY,IAAA,SAAI,GAAE,CAAC;QAC3B,MAAM,QAAQ,GAAY,IAAA,WAAI,EAAC,IAAA,WAAM,GAAE,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QAC5D,MAAM,GAAG,GAAmB,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,GAAG,GAAoB,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAElD,MAAM,IAAI,GAAY,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAA;QAC3C,MAAM,GAAG,GAAY,CAAC,CAAC;QACvB,MAAM,CAAC,GAAY,KAAK,GAAG,GAAG,CAAC;QAC/B,MAAM,CAAC,GAAY,MAAM,GAAG,GAAG,CAAC;QAChC,MAAM,OAAO,GAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;QACpD,MAAM,GAAG,GAAY,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,GAAG,OAAO,GAAG,EAAE,CAAC;QACjE,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;QACxB,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACzB,GAAG,CAAC,SAAS,GAAG,OAAO,CAAC;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAChC,GAAG,CAAC,SAAS,EAAE,CAAA;YACf,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;YACxB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAA;YAClC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,EAAE,OAAO,CAAC,CAAA;YAClC,GAAG,CAAC,IAAI,EAAE,CAAA;YACV,GAAG,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YAC5B,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,GAAG,CAAC,CAAA;YACzC,GAAG,CAAC,SAAS,CAAC,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC/B,CAAC;QAED,IAAI,CAAC;YACJ,MAAM,MAAM,CAAC,iBAAiB,CAAC,GAAG,EAAE,IAAA,sBAAiB,EAAC,QAAQ,CAAC,CAAC,CAAC;QAClE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,GAAG,CAAC;QACX,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;CACD;AA1DD,8BA0DC;AAED,MAAM,CAAC,OAAO,GAAG,EAAE,SAAS,EAAE,CAAC"}

View File

@ -43,6 +43,7 @@ let camera : Camera;
let sequence : Sequence; let sequence : Sequence;
let index : HandlebarsTemplateDelegate<any>; let index : HandlebarsTemplateDelegate<any>;
let focusImage : string = null; let focusImage : string = null;
let framingImage : string = null;
let port : number; let port : number;
let wsPort : number; let wsPort : number;
@ -206,7 +207,7 @@ async function cmd (msg : Message) {
await select(msg.state.sequence.hash); await select(msg.state.sequence.hash);
break; break;
case 'start' : case 'start' :
start(); await start();
break; break;
case 'stop' : case 'stop' :
stop(); stop();
@ -226,6 +227,9 @@ async function cmd (msg : Message) {
case 'focus' : case 'focus' :
await focus(); await focus();
break; break;
case 'framing' :
await framing();
break;
case 'offset' : case 'offset' :
offset(msg); offset(msg);
break; break;
@ -283,9 +287,12 @@ async function select (id : string) : Promise<boolean> {
return true; return true;
} }
function start () { async function start () {
if (focus !== null) { if (focusImage !== null) {
stopFocus(); await stopFocus();
}
if (framingImage !== null) {
await stopFraming();
} }
sequence.start(); sequence.start();
} }
@ -343,6 +350,44 @@ async function stopFocus () {
send({ cmd : 'unfocus' }); send({ cmd : 'unfocus' });
} }
async function framing () {
let pos : fdOutgoingPosition;
let dims : Dimensions;
let state : State;
let filePath : string;
if (framingImage !== null) {
await stopFraming();
return;
}
if (sequence.isLoaded()) {
state = sequence.getState();
pos = {
w : state.display.width,
h : state.display.height,
x : state.offset.x,
y : state.offset.y
}
} else {
dims = display.getScreen();
pos = {
w : dims.width,
h : dims.height,
x : 0,
y : 0
}
}
framingImage = await TestImage.Frame(pos.w, pos.h);
await fd.load (framingImage, pos.x, pos.y, pos.w, pos.h);
await fd.display(framingImage);
send({ cmd : 'framing' });
}
async function stopFraming () {
framingImage = null;
await fd.stop(framingImage);
send({ cmd : 'unframing' });
}
function offset (msg : Message) { function offset (msg : Message) {
let current : ImageObject = sequence.getCurrent(); let current : ImageObject = sequence.getCurrent();
if (current !== null) { if (current !== null) {
@ -384,6 +429,14 @@ app.get('/:width/:height/image.jpg', async (req : Request, res : Response, next
log.error(`Error getting thumbnail of ${current}`, err); log.error(`Error getting thumbnail of ${current}`, err);
return next(new Error('Error getting thumbnail')); return next(new Error('Error getting thumbnail'));
} }
} else if (framingImage !== null) {
try {
data = await image.thumbnail(framingImage, width, height);
log.info(`Image: ${current.path} - ${width},${height}`);
} catch (err) {
log.error(`Error getting thumbnail of ${current}`, err);
return next(new Error('Error getting thumbnail'));
}
} else if (current !== null) { } else if (current !== null) {
try { try {
data = await image.thumbnail(current.path, width, height); data = await image.thumbnail(current.path, width, height);

View File

@ -10,6 +10,8 @@ export class TestImage {
const filePath : string = join(tmpdir(), `frame-${id}.png`); const filePath : string = join(tmpdir(), `frame-${id}.png`);
const img : PImage.Bitmap = PImage.make(width, height); const img : PImage.Bitmap = PImage.make(width, height);
const ctx : PImage.Context = img.getContext('2d'); const ctx : PImage.Context = img.getContext('2d');
const halfW : number = Math.round(width / 2) - (edge > 1 ? Math.round(edge / 2) : 0);
const halfH : number = Math.round(height / 2) - (edge > 1 ? Math.round(edge / 2) : 0);
ctx.fillStyle = 'black'; ctx.fillStyle = 'black';
ctx.fillRect(0, 0, width, height); ctx.fillRect(0, 0, width, height);
ctx.fillStyle = 'red'; ctx.fillStyle = 'red';
@ -17,6 +19,8 @@ export class TestImage {
ctx.fillRect(0, 0, edge, height); ctx.fillRect(0, 0, edge, height);
ctx.fillRect(0, height - edge, width, edge); ctx.fillRect(0, height - edge, width, edge);
ctx.fillRect(width - edge, 0, edge, height); ctx.fillRect(width - edge, 0, edge, height);
ctx.fillRect(halfW, 0, edge, height);
ctx.fillRect(0, halfH, width, edge);
try { try {
await PImage.encodePNGToStream(img, createWriteStream(filePath)); await PImage.encodePNGToStream(img, createWriteStream(filePath));
} catch (err) { } catch (err) {

View File

@ -12,6 +12,7 @@ declare class Display {
private screen; private screen;
private sequence; private sequence;
private focus; private focus;
private framing;
private offsetX; private offsetX;
private offsetY; private offsetY;
private width; private width;
@ -40,6 +41,8 @@ declare class Display {
set(state: State): void; set(state: State): void;
setFocus(): void; setFocus(): void;
unsetFocus(): void; unsetFocus(): void;
setFraming(): void;
unsetFraming(): void;
private onResize; private onResize;
} }
declare class Client { declare class Client {
@ -87,6 +90,9 @@ declare class Client {
sendFocus(): void; sendFocus(): void;
private receiveFocus; private receiveFocus;
private receiveUnfocus; private receiveUnfocus;
sendFraming(): void;
private receiveFraming;
private receiveUnframing;
sendOffset(x: number, y: number): void; sendOffset(x: number, y: number): void;
sendSize(width: number, height: number): void; sendSize(width: number, height: number): void;
sendScale(scale: number): void; sendScale(scale: number): void;

View File

@ -9,6 +9,7 @@ class Display {
constructor() { constructor() {
this.sequence = false; this.sequence = false;
this.focus = false; this.focus = false;
this.framing = false;
this.offsetX = 0; this.offsetX = 0;
this.offsetY = 0; this.offsetY = 0;
this.width = 0; this.width = 0;
@ -73,7 +74,7 @@ class Display {
this.ctx.stroke(); this.ctx.stroke();
} }
updateDisplay() { updateDisplay() {
if (!this.sequence && !this.focus) { if (!this.sequence && !this.focus && !this.framing) {
return; return;
} }
const screenScaleX = this.screenWidth / this.screen.width; const screenScaleX = this.screenWidth / this.screen.width;
@ -110,6 +111,12 @@ class Display {
unsetFocus() { unsetFocus() {
this.focus = false; this.focus = false;
} }
setFraming() {
this.framing = true;
}
unsetFraming() {
this.framing = false;
}
onResize(event) { onResize(event) {
this.updateSize(); this.updateSize();
this.clear(); this.clear();
@ -275,6 +282,13 @@ class Client {
break; break;
case 'unfocus': case 'unfocus':
this.receiveUnfocus(msg); this.receiveUnfocus(msg);
break;
case 'framing':
this.receiveFraming(msg);
break;
case 'unframing':
this.receiveUnframing(msg);
break;
case 'display': case 'display':
this.receiveDisplay(msg); this.receiveDisplay(msg);
break; break;
@ -395,6 +409,18 @@ class Client {
this.display.unsetFocus(); this.display.unsetFocus();
this.display.updateImage(); this.display.updateImage();
} }
sendFraming() {
console.log('send framing');
this.client.send(JSON.stringify({ cmd: 'framing' }));
}
receiveFraming(msg) {
this.display.setFraming();
this.display.updateImage();
}
receiveUnframing(msg) {
this.display.unsetFraming();
this.display.updateImage();
}
sendOffset(x, y) { sendOffset(x, y) {
this.client.send(JSON.stringify({ cmd: 'offset', x, y })); this.client.send(JSON.stringify({ cmd: 'offset', x, y }));
} }

File diff suppressed because one or more lines are too long

View File

@ -120,7 +120,7 @@
<button id="open" class="manualCtrl" onclick="client.sendCameraOpen()">Open</button> <button id="open" class="manualCtrl" onclick="client.sendCameraOpen()">Open</button>
<button id="close" class="manualCtrl" onclick="client.sendCameraClose()">Close</button> <button id="close" class="manualCtrl" onclick="client.sendCameraClose()">Close</button>
<button id="focus" class="manualCtrl" onclick="client.sendFocus();">Focus</button> <button id="focus" class="manualCtrl" onclick="client.sendFocus();">Focus</button>
<button id="framing" class="manualCtrl" onclick="">Framing</button> <button id="framing" class="manualCtrl" onclick="client.sendFraming();">Framing</button>
</form> </form>
</fieldset> </fieldset>
</div> </div>