diff --git a/src/main/services/streamdeck/actions.ts b/src/main/services/streamdeck/actions.ts index d55b174..2350475 100644 --- a/src/main/services/streamdeck/actions.ts +++ b/src/main/services/streamdeck/actions.ts @@ -229,7 +229,7 @@ async function discardVerdict(clip: Clip): Promise { @@ -242,7 +242,21 @@ export async function latestPreview(): Promise { const file = await videoService.ensureThumbnail(clip); const image = nativeImage.createFromPath(file); if (!image.isEmpty()) { - thumbnail = `data:image/jpeg;base64,${image.resize({ height: 144 }).toJPEG(80).toString('base64')}`; + /* + * Cropped square here, not in the key's SVG. The Stream Deck app draws + * SVG with a renderer that ignores `preserveAspectRatio="... slice"`, so + * a 21:9 frame handed to it was squashed into the square key rather than + * covering it. The middle of the frame is where the action is. + */ + const { width, height } = image.getSize(); + const side = Math.min(width, height); + const square = image.crop({ + x: Math.floor((width - side) / 2), + y: Math.floor((height - side) / 2), + width: side, + height: side, + }); + thumbnail = `data:image/jpeg;base64,${square.resize({ width: 144, height: 144 }).toJPEG(82).toString('base64')}`; } } catch { // No picture is a key with a plain face, not a failed key. diff --git a/streamdeck-plugin/io.github.darrellvs.goodbit.sdPlugin/manifest.json b/streamdeck-plugin/io.github.darrellvs.goodbit.sdPlugin/manifest.json index 2c7626a..0fc6e6e 100644 --- a/streamdeck-plugin/io.github.darrellvs.goodbit.sdPlugin/manifest.json +++ b/streamdeck-plugin/io.github.darrellvs.goodbit.sdPlugin/manifest.json @@ -2,7 +2,7 @@ "$schema": "https://schemas.elgato.com/streamdeck/plugins/manifest.json", "UUID": "io.github.darrellvs.goodbit", "Name": "GoodBit", - "Version": "0.4.1.0", + "Version": "0.4.2.0", "Author": "GoodBit", "Description": "Save the replay, then tag, publish or discard the clip you just saved, and see today's count, without leaving the game. Needs GoodBit running with the Stream Deck connection switched on in Settings, Connections.", "URL": "https://darrellvs.github.io/goodbit/", diff --git a/streamdeck-plugin/src/actions/discard-latest.ts b/streamdeck-plugin/src/actions/discard-latest.ts index 811e4c5..fe75ae0 100644 --- a/streamdeck-plugin/src/actions/discard-latest.ts +++ b/streamdeck-plugin/src/actions/discard-latest.ts @@ -117,7 +117,9 @@ export class DiscardLatest extends SingletonAction { /** * The key's face as an SVG data URL, or '' for the plain icon from the manifest. * - * 144 square. The thumbnail fills it at nearly full brightness, because the + * 144 square. The thumbnail arrives already cropped square by GoodBit (the + * Stream Deck's SVG renderer ignores `slice` and would squash a wide frame), + * and fills the key at nearly full brightness, because the * picture is the point of the key: darkening the whole frame so the mark read * made the clip itself unreadable on the LCD. The mark sits on a small dark * disc of its own instead, trash in the danger colour, or a lock in the light @@ -131,7 +133,7 @@ function face(preview: Preview): string { const colour = kept ? '#f2efea' : '#d45757'; const svg = ` - + ${glyph}