aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
authorDanilo M. <danix@danix.xyz>2026-10-30 18:26:49 +0100
committerDanilo M. <danix@danix.xyz>2026-10-30 18:26:49 +0100
commit8553d49a0801d07e21ca9b4113b51181e6c7a72b (patch)
tree7accb511f9950bc0e2a7743259d398640004ea57 /docs
downloadupscale-qt-8553d49a0801d07e21ca9b4113b51181e6c7a72b.tar.gz
upscale-qt-8553d49a0801d07e21ca9b4113b51181e6c7a72b.zip
Initial commit: upscale-qt image upscaler GUI
PyQt6 app that upscales an image with an ESRGAN model through sd-cli, compares before and after with a slider wipe, and saves the result or overwrites the original. This commit holds the docs, license and design spec. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs')
-rw-r--r--docs/superpowers/specs/2026-10-30-upscale-qt-design.md81
1 files changed, 81 insertions, 0 deletions
diff --git a/docs/superpowers/specs/2026-10-30-upscale-qt-design.md b/docs/superpowers/specs/2026-10-30-upscale-qt-design.md
new file mode 100644
index 0000000..8db80a5
--- /dev/null
+++ b/docs/superpowers/specs/2026-10-30-upscale-qt-design.md
@@ -0,0 +1,81 @@
+# upscale-qt design
+
+## Goal
+
+Pick an image, preview it, upscale it with an ESRGAN model through `sd-cli`,
+check the result against the original, then save it as a new file or
+overwrite the original.
+
+## Stack
+
+Single file `upscale-qt`, Python 3 + PyQt6, no other dependencies. External
+binaries: `sd-cli` (required), `llama-mtmd-cli` (optional, for suggestions).
+
+## Window
+
+- Toolbar: Open, model dropdown, Upscale, Save As, Overwrite, Settings.
+- Center: compare view (one custom widget).
+- Status bar: current activity, suggestion result, last stderr line.
+
+Save As and Overwrite are disabled until an upscaled result exists. Upscale is
+disabled while a process runs or no model is selected.
+
+## Compare view
+
+- No result yet: shows the original only.
+- With result: the original is scaled to the result's size and drawn left of
+ a vertical divider, the result right of it.
+- Drag near the divider moves it. Drag elsewhere pans. Wheel zooms around
+ the cursor. Double-click resets to fit-to-window.
+- Before and after share one transform, so the same pixels line up.
+
+## Jobs
+
+Internally a list of jobs, each: source path, chosen model, result path
+(temp file) or None, state (idle, suggesting, upscaling, done, failed). The
+UI shows only the current job. Opening an image replaces the list with one
+job. Batch mode later adds UI over the same list.
+
+## Flow
+
+1. Open via file dialog or `argv[1]`. Image shown at once.
+2. If imajev is configured, run
+ `llama-mtmd-cli -m <model> --mmproj <mmproj> --image <src> -p <prompt>`,
+ the prompt listing the upscaler filenames and asking for exactly one back.
+ The answer is matched to a filename (exact filename, then stem, then
+ case-insensitive substring); a match preselects the dropdown and the
+ status bar says "imajev suggests X". No match or failure: dropdown
+ unchanged, status says so. The user can always change the dropdown.
+3. Upscale runs
+ `sd-cli -M upscale --upscale-model <dir/model> -i <src> -o <tmp>.png`.
+ The temp file lives in a `QTemporaryDir` for the app's lifetime.
+4. On exit code 0 with a readable output, the result loads into the compare
+ view. Otherwise a message box shows the last stderr lines.
+5. Save As: file dialog, format from the chosen extension.
+ Overwrite: confirmation dialog naming the file and new size, then save in
+ the original's format to `<file>.part` and rename over the original, so a
+ failed write never leaves a truncated original.
+
+## Settings
+
+`QSettings`: upscalers dir, imajev model path, imajev mmproj path, last open
+dir. Defaults point at the maintainer's model folders and are editable in a
+small Settings dialog. Missing upscalers dir or empty model list: Upscale
+disabled with a tooltip. Missing imajev files or binary: suggestion silently
+skipped.
+
+## Errors
+
+- Binary not found or crash: message box with the error.
+- Non-zero exit: message box with the stderr tail.
+- Unreadable input image: message box, job not created.
+
+## Testing
+
+`test_upscale_qt.py` with plain asserts for the non-GUI functions, at least
+the answer-to-filename matcher. GUI checked by hand, or headless with
+`QT_QPA_PLATFORM=offscreen`.
+
+## Out of scope for now
+
+Batch UI, choice of output scale, backup copies of overwritten files.