diff --git a/README.md b/README.md index a4243fb..16dc88e 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,22 @@ Perspective correction for paintings and rectangular objects. Takes a photo of a ## Quick start ```bash -# From source +# From source (Linux/macOS) python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt python -m rectify --gui photo.jpg ``` -Or download a pre-built executable from the releases page — no Python required. +On macOS there is also a ready-to-run signed app — see +[Installation methods](#installation-methods). ## Setup from source +The repository is public — no account, login, or permission is needed to clone +it. It can also be browsed, and downloaded as a ZIP, at +. + ```bash git clone https://git.andykopra.com/ack/rectify.git cd rectify @@ -24,11 +29,66 @@ source .venv/bin/activate pip install -r requirements.txt ``` +The GUI is the primary interface on every platform; the CLI drives the same +engine without a window, for scripting and batch work. + **Platform notes:** -- **Linux:** May need `sudo apt install libxcb-xinerama0 libxcb-cursor0` for Qt -- **macOS:** Works with Homebrew or python.org Python +- **Linux:** See [Run from source on Linux](#run-from-source-on-linux) below +- **macOS:** Works with Homebrew or python.org Python (Apple silicon and Intel). + For day-to-day use, install `Rectify.dmg` instead of running from source - **Windows:** See [Run from source on Windows](#run-from-source-on-windows) below +### Run from source on Linux + +Linux is the platform Rectify is developed on, so it is the best-tested of the +three. There is no packaged download the way macOS has its `.dmg` — you run it +from source. Development happens on Ubuntu with GNOME; any current distribution +with Python 3.10+, `git`, and a graphical desktop works, and only the `apt` +command lines below are Ubuntu-specific. + +Start with the public clone in [Setup from source](#setup-from-source) above — +`git clone https://git.andykopra.com/ack/rectify.git`, no account needed. + +**Debian/Ubuntu need one package before the venv step** — without it, +`python3 -m venv` fails with `ensurepip is not available`: + +```bash +sudo apt install python3-venv python3-pip +``` + +Then follow [Setup from source](#setup-from-source) above and launch: + +```bash +source .venv/bin/activate +python -m rectify --gui photo.jpg +``` + +**If something goes wrong:** + +- *PySide6 fails to start* — install the X11/XCB libraries Qt needs: + `sudo apt install libxcb-xinerama0 libxcb-cursor0` +- *Window sizing, cursors, or tooltips look wrong (or the app won't start) in a + Wayland session* — force the X11 path with + `QT_QPA_PLATFORM=xcb python -m rectify --gui`. Worth trying first for any + display oddity, especially on NVIDIA drivers +- *HEIC files show a generic icon in the Open dialog* — thumbnails come from your + desktop, not from Rectify (which reads them fine either way). Run + `scripts/install_heic_thumbnailer.sh` once; it self-skips if your system + already handles HEIC + +**Launching from anywhere.** The venv's own interpreter can run Rectify directly, +so a one-line wrapper (saved as `~/bin/rectify`, `chmod +x`) avoids activating +the venv each time and keeps relative filenames working: + +```sh +#!/bin/sh +exec env PYTHONPATH="$HOME/rectify" "$HOME/rectify/.venv/bin/python" -m rectify "$@" +``` + +For a clickable icon, point a `~/.local/share/applications/rectify.desktop` +entry at that wrapper with `Exec=/home/YOUR_USER/bin/rectify --gui %f`. Per-user +settings are written to `~/.local/share//Rectify/settings.json`. + ### Run from source on Windows Every dependency ships a Windows wheel — PySide6 bundles Qt and `pillow-heif` @@ -38,8 +98,9 @@ dialog, with image thumbnails. **Prerequisites:** Python 3.10–3.13 from [python.org](https://www.python.org/downloads/windows/) — tick **"Add python.exe -to PATH"** in the installer. `git` is optional; you can download the repository -as a ZIP instead. +to PATH"** in the installer. `git` is optional; the public repository can be +downloaded as a ZIP from instead. Either +way, no account or permission is needed. **PowerShell:** @@ -86,8 +147,9 @@ each behaves: 1. Opening a **HEIC/HEIF** photo from an iPhone. 2. Display scaling at 125% and 150% — menu, panel, and control sizing. -3. The keyboard shortcuts (press **Shift+Alt** for the overlay) — all use Ctrl - on Windows. +3. The keyboard shortcuts — press **Shift-Alt** for the overlay. On Windows, + Ctrl and Alt stand in for the ⌘ and ⌥ used in the + [shortcut table](#keyboard-shortcuts) below. 4. Saving to a folder whose path contains spaces. 5. Building an executable with `pyinstaller rectify.spec` (see [Building a standalone executable](#building-a-standalone-executable)) and @@ -113,8 +175,8 @@ The GUI provides: - **Color correct** — recover accurate color when a neutral reference is in the frame. Tick **Color correct**, then choose a reference mode — **Gray** or **White** (neither is preselected; pick the one that matches your reference). Click the swatch, then click the reference area in the left image; Rectify averages a small square around that point — its side length in pixels is the **Sample size** (1 = just the clicked pixel; default 10 = a 10×10 block) — and white-balances the output so the patch becomes neutral. **Gray** mode (a gray card, or any surface you trust as neutral gray) couples color and exposure: the **Reflectance** value is the target tone the patch is mapped to, in the photographer's unit — default **18%** (standard middle-gray card); set it to your card's rating (e.g. 12%) or adjust to taste (adjustable 3–80%). **White** mode (a white sheet or other white reference) *decouples* them: it neutralizes the color cast while keeping the patch's own brightness — so white is **not** forced to maximum and anything brighter (a highlight, a lamp) keeps its headroom — and a centered **Brightness** slider (0 = unchanged) then raises or lowers the whole result independently. The swatch shows the sampled color and turns red if the spot is too bright or too dark to use; a 2-pixel-wide red border marks the sampled region, with the averaged pixels just inside it. Sample the card outside the artwork — it's read from the source image but the correction is applied to the result, in every mode. **The measured gray is sticky:** shoot one reference frame with a gray card, pick it once, then for other images taken under the same light just tick Color correct and they reuse that gray automatically (no need for a card in every shot). Reusing a gray takes a frozen *snapshot* — re-picking the reference later won't silently change images that already borrowed it. **Left-click** the swatch to pick a gray on the current image; **right-click** it to re-apply the last-used gray (handy when an image already has its own value you want to replace). An image you picked on keeps its own measurement and shows the red marker; one using a borrowed gray shows the color in the swatch but no marker - **Corner dragging** — click and drag corners; arrow keys for 1-pixel nudge - **Edge dragging** — click near an edge and drag to move it perpendicular to itself; arrow keys for fine nudging -- **Ctrl+Left-Click** — moves the nearest movable point (a quad corner in Extract mode, a keystone-line arrow handle in Lines mode) to the click position. Designed for precision adjustment while zoomed in; the cursor becomes a crosshair whenever Ctrl is held so you know the gesture is armed -- **Alt+Left-Click ×2** — draws a red antialiased "alternate-line" annotation between two clicked points. Useful for sketching what auto-detection *should* produce in screenshots and bug reports. A dashed rubber-band tracks the cursor between the first and second click; multiple annotations accumulate; Esc clears them all (and any temporary marks in general); a new image load also clears. +- **⌘-Left-Click** — moves the nearest movable point (a quad corner in Extract mode, a keystone-line arrow handle in Lines mode) to the click position. Designed for precision adjustment while zoomed in; the cursor becomes a crosshair whenever ⌘ is held so you know the gesture is armed +- **⌥-Left-Click ×2** — draws a red antialiased "alternate-line" annotation between two clicked points. Useful for sketching what auto-detection *should* produce in screenshots and bug reports. A dashed rubber-band tracks the cursor between the first and second click; multiple annotations accumulate; Esc clears them all (and any temporary marks in general); a new image load also clears. - **Alignment indicator** — edges turn blue when their endpoints are vertically or horizontally aligned (same x or y value); the same blue/green indicator applies to keystone-line pairs in Lines mode - **Subregion selection** — click in the center of the quad and drag to reposition; scroll wheel while dragging to resize. Use with Peel in to extract individual subjects from multi-subject photos - **Peel stack** — Peel in/out to strip successive frame layers; left panel always shows the original with mapped-back overlay @@ -122,35 +184,45 @@ The GUI provides: - **Keystone correction** — remove vertical and/or horizontal keystone distortion using line pairs. Draw one or two pairs of lines on features known to be parallel (e.g., building edges, door frames); the correction makes them parallel in the output. Arrow-shaped handles distinguish lines from the quad overlay - **Stretch** (Transform → Lines) — keystone correction straightens converging lines but can't recover how wide the result should be relative to its height (the lines carry no scale, and there's no reference rectangle as in Quad mode). The **Stretch** slider is a by-eye correction for that residual width-to-height relationship: 1.00 leaves the width unchanged, above 1.00 widens, below narrows. Shown only in Lines mode; remembered per image - **Saving** — one **Save** button with an **Increment** checkbox. The default output name is the source image's name with **`_rectified`** appended (e.g. `hotel.png` → `hotel_rectified.png`), so a save never overwrites the input. With Increment **off**, Save opens a dialog (pre-filled with that default) where the extension you type picks the format (png/jpg/jpeg/tiff/tif/webp/bmp; an unsupported type is rejected with the supported list). With Increment **on**, Save writes the next auto-numbered file (`hotel_rectified_1`, `hotel_rectified_2`, …) with one click — no dialog. Both modes share the last-used folder and type; folder, type, and the Increment setting persist across sessions -- **Undo/redo** — Ctrl+Z / Ctrl+Shift+Z for corner adjustments (keyboard only) +- **Undo/redo** — ⌘-Z / ⌘-Shift-Z for corner adjustments (keyboard only) - **Drag and drop** — drop an image file onto the window - **Before/after** — hold Space to compare - **Tooltips** — hover any control for a short explanation in a readable boxed popup; toolbar buttons also show their keyboard shortcut. Fully translated in all three interface languages -- **Settings persistence** — all preferences (including your last save folder, file type, and Increment mode), window layout, and per-image state (corners, keystone lines, bow value, Stretch value, color-correction sample, plus any manual override of the aspect ratio) cached for every image you've touched. Switch between images with Ctrl+↑/↓ while preparing a batch; come back to any image and your tuning is intact. Saved on close and restored on next launch +- **Settings persistence** — all preferences (including your last save folder, file type, and Increment mode), window layout, and per-image state (corners, keystone lines, bow value, Stretch value, color-correction sample, plus any manual override of the aspect ratio) cached for every image you've touched. Switch between images with ⌘-↑/↓ while preparing a batch; come back to any image and your tuning is intact. Saved on close and restored on next launch ### Keyboard shortcuts | Shortcut | Action | |----------|--------| -| Ctrl+O | Open image | -| Ctrl+S | Save (opens the dialog, or writes the next auto-numbered file when Increment is on) | -| Ctrl+D | Reset (re-detect from scratch) | -| Ctrl+R | Re-open the current file (re-read pixels from disk; per-image cache preserves corners, keystone pairs, bow) | -| Ctrl+↓ / Ctrl+↑ | Load next / previous image in the current directory (wraps around) | -| Ctrl+Z | Undo | -| Ctrl+Shift+Z | Redo | +| ⌘-O | Open image | +| ⌘-S | Save (opens the dialog, or writes the next auto-numbered file when Increment is on) | +| ⌘-D | Reset (re-detect from scratch) | +| ⌘-R | Re-open the current file (re-read pixels from disk; per-image cache preserves corners, keystone pairs, bow) | +| ⌘-↓ / ⌘-↑ | Load next / previous image in the current directory (wraps around) | +| ⌘-Z | Undo | +| ⌘-Shift-Z | Redo | | + or = | Peel in | | - | Peel out | | Space (hold) | Before/after comparison | | Arrow keys | Nudge selected corner, edge, or whole quad | | Mouse wheel | Zoom (or adjust element with Shift or left-button held) | -| Shift + wheel | Adjust quad element under cursor (corner, edge, or whole quad) | -| Ctrl + Left-click | Snap the nearest point (corner or line endpoint) to the click position | -| Alt + Left-click ×2 | Draw a red alternate-line annotation between two clicks | +| Shift-wheel | Adjust quad element under cursor (corner, edge, or whole quad) | +| ⌘-Left-click | Snap the nearest point (corner or line endpoint) to the click position | +| ⌥-Left-click ×2 | Draw a red alternate-line annotation between two clicks | | Esc | Clear temporary marks (annotations, etc.) | | Right-click | Reset zoom on clicked panel | | 0 | Reset zoom on both panels | -| Shift+Alt (hold) | Show keyboard-shortcut overlay (centered popup) | +| Shift-⌥ (hold) | Show keyboard-shortcut overlay (centered popup) | + +Keys are written with the macOS symbols **⌘** (Command) and **⌥** (Option). +**On Linux and Windows, read Ctrl for ⌘ and Alt for ⌥** — ⌘-O is Ctrl-O, ⌘-click +is Ctrl-click, Shift-⌥ is Shift-Alt. That substitution is the whole difference; +no shortcut exists on one system and not another. Two macOS-only details: ⌃-click +— the physical Control key — is just how a one-button mouse delivers a +right-click, while ⌘-click is the snap gesture; and combinations containing Shift +are shown in Apple's order on screen (⇧-⌘-Z, ⌥-⇧), the same keys as the +⌘-Shift-Z and Shift-⌥ above. Rectify labels its own tooltips and overlay for the +system you are on. The same shortcut table is printed by `rectify -k` (also `--keyboard`), so you can read it without opening the GUI. @@ -184,33 +256,19 @@ The GUI always runs the automatic two-pass sweep — both detection strategies, ## Installation methods -### Pre-built executables +### Pre-built application -Download the executable for your platform from the releases page. No Python installation is required. +**macOS** is the only platform with a published build: a signed, notarized +`Rectify.dmg` that needs no Python installation. -**Linux:** -```bash -chmod +x rectify -./rectify --gui photo.jpg -``` - -**macOS:** -- Download `Rectify.dmg`, open it, and drag `Rectify.app` to your Applications folder +- Open the `.dmg` and drag `Rectify.app` to your Applications folder - Double-click `Rectify.app` to launch — it opens the GUI with a file dialog - You can also drag an image file onto the `Rectify.app` icon in Finder or the Dock to open it directly -- Or download the command-line executable and run from Terminal: -```bash -chmod +x rectify -./rectify --gui photo.jpg -``` -**Windows:** -- Download `rectify.exe` -- Double-click to launch (opens the GUI with a file dialog) -- Or run from Command Prompt / PowerShell: -```powershell -.\rectify.exe --gui photo.jpg -``` +**Linux and Windows** run from source ([above](#setup-from-source)). You can +build a standalone executable yourself if you want one — see +[Building a standalone executable](#building-a-standalone-executable) — but it is +not required, and running from source is the normal path on both. ### Building a standalone executable diff --git a/doc/Rectify_user_guide.md b/doc/Rectify_user_guide.md index 02d9d31..b34bdb6 100644 --- a/doc/Rectify_user_guide.md +++ b/doc/Rectify_user_guide.md @@ -31,7 +31,7 @@ This guide is divided into four parts: - [1.4 A word about color](#14-a-word-about-color) - [1.5 Two ways to use Rectify](#15-two-ways-to-use-rectify) - [2. Using Rectify](#2-using-rectify) - - [2.1 Installing Rectify on macOS](#21-installing-rectify-on-macos) + - [2.1 Installing Rectify](#21-installing-rectify) - [2.2 The main window](#22-the-main-window) - [2.3 Opening images](#23-opening-images) - [2.4 How detection works, and the vocabulary](#24-how-detection-works-and-the-vocabulary) @@ -185,14 +185,18 @@ from the ground up, and the earlier sections link to it where useful. Rectify is one program with two front ends: -- **The graphical application (GUI)** is the primary way to use it, and the - subject of [§2](#2-using-rectify). It is interactive: you see the detected - region, drag it into place, and watch the corrected result update live. On - macOS it is delivered as a ready-to-run `Rectify.dmg`. +- **The graphical application (GUI)** is the primary way to use Rectify on every + platform, and the subject of [§2](#2-using-rectify). It is interactive: you see + the detected region, drag it into place, and watch the corrected result update + live. On macOS it is delivered as a ready-to-run `Rectify.dmg`; on Linux and + Windows you run it from source and launch it with `python -m rectify --gui` + (see [§2.1](#21-installing-rectify)). The window and every feature in it are + identical on all three. - **The command line (CLI)** drives the same engine without a window, for - scripting and batch processing. On Linux, where Rectify is run from source, the - command line is the primary way to interact with it. The CLI is documented in - [§3.3](#33-the-command-line-interface). + scripting and batch processing — correcting a whole folder of photos in a loop, + for instance, without touching the GUI at all. It is available on all three + platforms (on macOS from the source tree, not the app bundle) and is documented + in [§3.3](#33-the-command-line-interface). ## 2. Using Rectify @@ -202,7 +206,28 @@ photography either; the later ones (aspect ratio, bow, color) assume you are comfortable with ordinary photographic ideas, and point you to the [primer in §4.14](#414-color-theory-primer) when a deeper concept comes up. -### 2.1 Installing Rectify on macOS +Everything here applies equally to macOS, Linux, and Windows — the window, the +controls, and the gestures are the same on all three. Only two things differ: +how you install and launch the program ([§2.1](#21-installing-rectify)), and the +names of two keys. + +**How keys are written in this guide.** Shortcuts are printed throughout with the +macOS symbols, **⌘** (Command) and **⌥** (Option). **If you are on Linux or +Windows, press Ctrl wherever this guide shows ⌘, and Alt wherever it shows ⌥** — +so ⌘-O means Ctrl-O, ⌘-Click means Ctrl-Click, and Shift-⌥ means Shift-Alt. That +single substitution is the whole difference; no shortcut exists on one system and +not another. Rectify labels its own tooltips and its shortcut overlay for the +system you are actually on, so what you see on screen always matches your +keyboard. + +### 2.1 Installing Rectify + +Rectify is delivered in two forms: as a ready-to-run application on macOS, and as +source code you run with Python on Linux and Windows. Pick the section for your +system; from [§2.2](#22-the-main-window) onward the guide is the same for +everyone. + +#### macOS — the Rectify application You have been given a file named **`Rectify.dmg`**. To install: @@ -223,6 +248,65 @@ confirm; you only need to do this once. Rectify runs on both Apple-silicon (M-series) and Intel Macs. There is nothing else to install — everything it needs is inside the app. +#### Linux — from source + +There is no packaged download for Linux; you fetch the source once, install its +Python dependencies into a self-contained folder, and launch the same GUI from a +terminal. It is about five commands, and you only do it once. + +Start by cloning the public repository — no account, login, or permission is +needed: + +```bash +git clone https://git.andykopra.com/ack/rectify.git +cd rectify +``` + +You can also browse it in a web browser at +, and download it there as a ZIP if you +would rather not use `git`. From that point, the step-by-step instructions — +including the two or three things that can go wrong on a fresh machine — are in +[§3.1](#31-installation), written to be followed without any Python knowledge. + +Afterwards, each session starts like this: + +```bash +cd ~/rectify # wherever you put the source +source .venv/bin/activate +python -m rectify --gui # or: python -m rectify --gui photo.jpg +``` + +[§3.1](#31-installation) also shows how to reduce that to a single command you +can type anywhere, or to a desktop icon you click. Once the window is open, +everything from [§2.2](#22-the-main-window) onward applies unchanged. + +#### Windows — from source + +Windows works the same way: there is no installer, you run the program from +source. Every component ships as a ready-built Windows package, so nothing has to +be compiled and no system libraries are needed. + +Start by cloning the public repository — no account, login, or permission is +needed. In PowerShell: + +```powershell +git clone https://git.andykopra.com/ack/rectify.git +cd rectify +``` + +You can also browse it in a web browser at + and use its download button to get a ZIP +instead, which avoids installing `git` at all. From that point, full instructions +are in [§3.1](#31-installation). + +Afterwards, each session starts like this, in PowerShell: + +```powershell +cd ~\rectify +.\.venv\Scripts\Activate.ps1 +python -m rectify --gui # or: python -m rectify --gui photo.jpg +``` + ### 2.2 The main window When Rectify opens, the window has five areas, top to bottom: @@ -270,7 +354,8 @@ displays. There are several ways to load a photo: - Click **Open** (or press **⌘-O**) and choose a file. -- **Drag an image file** from the Finder directly onto the Rectify window. +- **Drag an image file** from your file manager (Finder, Explorer, Files, …) + directly onto the Rectify window. - Once an image is open, press **⌘-↓ / ⌘-↑** to step to the **next / previous** image in the same folder (it wraps around at the ends). This is the fast way to work through a folder of photos — each one is detected fresh as it loads. @@ -284,6 +369,12 @@ tone are already applied — color correction works on the residual cast, not ra sensor data (see the [primer](#414-color-theory-primer)). Saved output is always one of the standard formats; HEIC is read-only. +The **Open** dialog itself is your system's own: Finder's panel on macOS, +Explorer's on Windows, and your desktop's file chooser on Linux. Its *thumbnails* +therefore come from the system, not from Rectify — so on an older Linux +distribution HEIC files may show a generic icon even though Rectify opens them +perfectly well. A one-time fix is in [§3.1](#31-installation). + When an image loads, Rectify immediately evaluates the detection and shows you the best result — the green quadrilateral on the left, the straightened result on the right. From there you refine by hand as needed. @@ -730,15 +821,17 @@ Because each image's edits live in this per-image memory, you can prepare a whol set in one session — adjusting corners, lines, bow, color, and aspect on each — just by stepping between them with ⌘-↑/↓, without saving to disk between switches. -The preferences file is stored per-user, so multiple users on one Mac keep -independent settings: +The preferences file is stored per-user, so several people sharing one computer +keep independent settings: | Platform | Location | |---|---| | macOS | `~/Library/Application Support//Rectify/settings.json` | +| Linux | `~/.local/share//Rectify/settings.json` | +| Windows | `%APPDATA%\\Rectify\settings.json` | (It is plain JSON and can be edited by hand if you ever need to, though normally -you never will. The Linux location is noted in [§3.1](#31-installation).) +you never will. Deleting it resets Rectify to a first-run state.) ### 2.16 Keyboard shortcuts @@ -755,14 +848,28 @@ you never will. The Linux location is noted in [§3.1](#31-installation).) | Space (hold) | Show the original in the right panel (before/after) | | Arrow keys | Nudge the selected corner, edge, or whole quad | | Mouse wheel | Zoom (or adjust the element under the cursor with Shift held) | -| Shift + wheel | Adjust the quad element under the cursor | -| ⌘ + Left-click | Snap the nearest point to the click position | -| Right-click | Reset zoom on the clicked panel | +| Shift-wheel | Adjust the quad element under the cursor | +| ⌘-Left-click | Snap the nearest point to the click position | +| ⌥-click ×2 | Draw an alternate-line annotation between two clicks | +| Right-click (or ⌃-click) | Reset zoom on the clicked panel | | 0 | Reset zoom on both panels | | Esc | Clear temporary marks | -| Shift+Option (hold) | Show the keyboard-shortcut overlay (release to dismiss) | +| Shift-⌥ (hold) | Show the keyboard-shortcut overlay (release to dismiss) | -Hold **Shift+Option** at any time to see this table without leaving the window. +**On Linux and Windows:** read **Ctrl** for ⌘ and **Alt** for ⌥ throughout the +table — ⌘-O is Ctrl-O, ⌘-click is Ctrl-click, Shift-⌥ is Shift-Alt. Everything +else is identical. + +Hold **Shift-⌥** at any time to see this table without leaving the window, with +the key names for the system you are on. The same table is printed by +`rectify -k` from the command line. + +Two macOS-only details are worth knowing. **⌘-click** snaps the nearest point, +while **⌃-click** — the *physical* Control key — is simply how a Mac delivers a +right-click on a one-button mouse or trackpad, and so resets the panel's zoom. +And where a combination includes Shift, the on-screen overlay follows Apple's +ordering and puts it first, as ⇧-⌘-Z and ⌥-⇧ — the same keys as the ⌘-Shift-Z +and Shift-⌥ written above, listed in the other order. ### 2.17 When automatic detection struggles @@ -803,26 +910,42 @@ program is built and operated, and it links to #### macOS (the app) For day-to-day use on a Mac, install the supplied `Rectify.dmg` exactly as in -[§2.1](#21-installing-rectify-on-macos) — drag the app to Applications. That bundle +[§2.1](#21-installing-rectify) — drag the app to Applications. That bundle is a self-contained build (Python, Qt, and OpenCV included) and needs nothing else. To *develop* on macOS instead, follow the from-source steps below; they work on macOS with Homebrew or python.org Python (Apple silicon and Intel). #### Linux (from source) -On Linux, Rectify is run from source, and the **command line is the primary way to -interact with it** (the GUI is available too, and behaves as described in §2). +Linux is the platform Rectify is developed on, so it is the best-tested of the +three — but there is no packaged download the way macOS has its `.dmg`. You run +it from source, and the **GUI is the primary interface here as everywhere else** +(the CLI in [§3.3](#33-the-command-line-interface) is the same engine without a +window, for scripting and batch work). -**Prerequisites:** Python 3.10 or later, `pip`, and `git`. +**Prerequisites:** Python 3.10 or later, `pip`, `git`, and a graphical desktop. +Development happens on Ubuntu with GNOME; any current distribution with those +pieces works, and nothing below is Ubuntu-specific except the `apt` command +lines, which have direct equivalents in `dnf`, `pacman`, and `zypper`. -1. **Obtain the source tree.** +1. **Clone the public repository.** It is open to everyone — no account, login, + or permission is required, and it can be browsed (and downloaded as a ZIP) at + . ```bash git clone https://git.andykopra.com/ack/rectify.git cd rectify ``` -2. **Create a virtual environment and install dependencies:** +2. **Make sure Python can create virtual environments.** Debian and Ubuntu ship + Python without this piece, and step 3 fails with `ensurepip is not available` + if it is missing: + + ```bash + sudo apt install python3-venv python3-pip + ``` + +3. **Create a virtual environment and install dependencies:** ```bash python3 -m venv .venv @@ -832,20 +955,16 @@ interact with it** (the GUI is available too, and behaves as described in §2). This pulls in OpenCV, NumPy, PySide6 (Qt), Pillow, and `pillow-heif` (HEIC/HEIF reading — it bundles its own `libheif`, so no system library is required). + Everything lands inside `.venv/`; nothing is installed system-wide, and + deleting the source folder removes all of it. -3. **Qt system libraries.** If PySide6 fails to start, install the X11/XCB +4. **Qt system libraries.** If PySide6 fails to start, install the X11/XCB libraries Qt needs. On Ubuntu/Debian: ```bash sudo apt install libxcb-xinerama0 libxcb-cursor0 ``` -4. **(Optional) HEIC thumbnails in the file chooser.** Rectify reads HEIC - regardless, but the **Open** dialog's thumbnails come from your desktop, which - on older distributions can't render iPhone HDR HEICs. Run - `scripts/install_heic_thumbnailer.sh` once to enable them (it self-skips if your - system already handles HEIC). - 5. **Run it:** ```bash @@ -856,9 +975,55 @@ interact with it** (the GUI is available too, and behaves as described in §2). python -m rectify photo.jpg -o rectified.jpg # CLI, no window ``` +6. **(Optional) HEIC thumbnails in the file chooser.** Rectify reads HEIC + regardless, but the **Open** dialog's thumbnails come from your desktop, which + on older distributions can't render iPhone HDR HEICs. Run + `scripts/install_heic_thumbnailer.sh` once to enable them (it self-skips if your + system already handles HEIC). + +**Launching without the two-step dance.** The virtual environment's own +interpreter can run Rectify directly, so a one-line wrapper lets you start it +from any directory, with relative filenames intact. Save this as +`~/bin/rectify` and `chmod +x` it, substituting your own path: + +```bash +#!/bin/sh +exec env PYTHONPATH="$HOME/rectify" "$HOME/rectify/.venv/bin/python" \ + -m rectify "$@" +``` + +Then `rectify --gui photo.jpg` works anywhere. For a clickable icon, point a +desktop entry at that wrapper — save the following as +`~/.local/share/applications/rectify.desktop`: + +```ini +[Desktop Entry] +Type=Application +Name=Rectify +Exec=/home/YOUR_USER/bin/rectify --gui %f +Terminal=false +Categories=Graphics;Photography; +MimeType=image/jpeg;image/png;image/tiff;image/webp;image/bmp;image/heif; +``` + +It then appears in your application menu, and images can be opened with it from +the file manager. + +**If the window misbehaves on Wayland.** Qt picks Wayland automatically in a +Wayland session. If Rectify fails to start, or the window's sizing, cursors, or +tooltip placement look wrong there, force the X11 path for one run: + +```bash +QT_QPA_PLATFORM=xcb python -m rectify --gui +``` + +If that fixes it, put `export QT_QPA_PLATFORM=xcb` in the wrapper script above. +This is worth trying first for any display-related oddity, particularly on NVIDIA +drivers, where Wayland compositor bugs are still common. + On Linux the per-user settings file lives at -`~/.local/share//Rectify/settings.json` (the macOS path is in -[§2.15](#215-what-rectify-remembers)). +`~/.local/share//Rectify/settings.json`; all three platforms' paths are +listed in [§2.15](#215-what-rectify-remembers). #### Windows (from source) @@ -873,7 +1038,10 @@ the standard Explorer dialog, complete with image thumbnails. python.exe to PATH"** ticked. `git` is optional — the repository can be downloaded as a ZIP instead. -1. **Obtain the source tree and create a virtual environment.** In PowerShell: +1. **Clone the public repository and create a virtual environment.** The + repository is open to everyone — no account, login, or permission is required, + and it can be browsed (and downloaded as a ZIP, if you would rather not + install `git`) at . In PowerShell: ```powershell git clone https://git.andykopra.com/ack/rectify.git @@ -1012,7 +1180,8 @@ python -m rectify --gui photo.jpg --debug my_debug.log # custom path, GU ``` **Keyboard reference:** `rectify -k` (also `--keyboard`) prints the shortcut table -(the same one the GUI shows on Shift+Option). +(the same one the GUI shows on Shift-⌥), with the key names of whichever system +it is run on. **Note:** color correction ([§2.12](#212-color-correction)) is interactive — it depends on clicking a reference in the image — so it is a GUI-only feature; the @@ -1091,11 +1260,12 @@ Connect them to detection or display methods via Qt signals, and wrap programmat updates in `blockSignals(True/False)` to avoid cascading recomputation. See [§4.13](#413-gui-architecture-internals). -**Diagnostic aids built into the GUI.** `Ctrl+Shift+E` toggles a Canny edge-detection +**Diagnostic aids built into the GUI.** `⇧-⌘-E` toggles a Canny edge-detection overlay on the left panel (red edges over the source, using the grayscale -defaults) — useful for seeing what the detector sees. `Ctrl+Shift+Delete` (or -`Ctrl+Shift+Backspace`) clears the settings cache and resets all controls to -defaults. Two environment variables draw layout-debugging overlays for GUI work: +defaults) — useful for seeing what the detector sees. `⇧-⌘-Delete` (or +`⇧-⌘-Backspace`) clears the settings cache and resets all controls to +defaults. (As everywhere in this guide, read those as `Ctrl-Shift-E` and +`Ctrl-Shift-Delete` on Linux and Windows.) Two environment variables draw layout-debugging overlays for GUI work: `RECTIFY_DEBUG_BORDERS=1` outlines every widget, and `RECTIFY_DEBUG_BASELINES=1` draws a red line at each text widget's baseline. diff --git a/rectify/gui.py b/rectify/gui.py index 3dd7141..6f237ed 100644 --- a/rectify/gui.py +++ b/rectify/gui.py @@ -3824,8 +3824,9 @@ class RectifyMainWindow(QMainWindow): def _retranslate(self): """Update all UI text for the current language.""" # Toolbar buttons. Tooltips append the keyboard shortcut, using the - # platform's modifier glyph (⌘ on macOS, "Ctrl+" elsewhere). - mod = "⌘" if _IS_MAC else "Ctrl+" + # platform's modifier glyph (⌘ on macOS, "Ctrl" elsewhere), joined + # with a hyphen on both — see rectify/shortcuts.py's module docstring. + mod = "⌘-" if _IS_MAC else "Ctrl-" self.btn_open.setText(T("open")) self.btn_open.setToolTip(tip(f"{T('open_tip')} ({mod}O)")) self.btn_reset.setText(T("reset_detect")) diff --git a/rectify/shortcuts.py b/rectify/shortcuts.py index 202c683..f18de0e 100644 --- a/rectify/shortcuts.py +++ b/rectify/shortcuts.py @@ -11,6 +11,14 @@ as the native symbols (⌘ ⌥ ⇧), reflecting Qt's Ctrl↔Cmd swap — the app explicit macOS label (an optional 3rd tuple element); notably the secondary-click panel-zoom reset is ⌃-click (physical Control), which macOS delivers as a right-click, while ⌘-click is the snap gesture. + +Parts of a combination are joined with a **hyphen on every platform** +("Ctrl-O", "⌘-O"), rather than Apple's tight ⌘O. The Apple glyphs have +very small side bearings, so a symbol butted against the next character +reads as one blob; the hyphen buys the separation the glyph itself does +not provide, and keeps the documentation identical in shape on all three +platforms. These strings are display labels only — the real bindings are +QKeySequence specs in gui.py and keep Qt's "Ctrl+X" syntax. """ import sys @@ -20,16 +28,16 @@ _IS_MAC = sys.platform == "darwin" # (section_i18n_key, ((keys, action_i18n_key[, macos_keys]), ...)) SECTIONS = ( ("sk_sec_file", ( - ("Ctrl+O", "open"), - ("Ctrl+S", "save"), - ("Ctrl+D", "reset_detect"), - ("Ctrl+R", "reopen"), - ("Ctrl+↓", "sk_next_image"), - ("Ctrl+↑", "sk_prev_image"), + ("Ctrl-O", "open"), + ("Ctrl-S", "save"), + ("Ctrl-D", "reset_detect"), + ("Ctrl-R", "reopen"), + ("Ctrl-↓", "sk_next_image"), + ("Ctrl-↑", "sk_prev_image"), )), ("sk_sec_edit", ( - ("Ctrl+Z", "undo"), - ("Ctrl+Shift+Z", "redo"), + ("Ctrl-Z", "undo"), + ("Ctrl-Shift-Z", "redo"), )), ("sk_sec_peel", ( ("+ or =", "peel_in"), @@ -44,31 +52,35 @@ SECTIONS = ( ("sk_sec_quad", ( ("← → ↑ ↓", "sk_nudge"), ("Shift", "sk_highlight"), - ("Shift + Wheel", "sk_adjust_highlighted"), - ("Ctrl+Click", "sk_snap_nearest", "⌘-click"), + ("Shift-Wheel", "sk_adjust_highlighted"), + ("Ctrl-Click", "sk_snap_nearest", "⌘-click"), )), ("sk_sec_dev", ( - ("Alt+Click ×2", "sk_annotate_line", "⌥-click ×2"), + ("Alt-Click ×2", "sk_annotate_line", "⌥-click ×2"), ("Esc", "sk_clear_temp"), - ("Ctrl+Shift+Del", "sk_clear_cache"), - ("Ctrl+Shift+E", "sk_edge_debug"), - ("Ctrl+Shift+W", "sk_screenshot"), + ("Ctrl-Shift-Del", "sk_clear_cache"), + ("Ctrl-Shift-E", "sk_edge_debug"), + ("Ctrl-Shift-W", "sk_screenshot"), )), ("sk_sec_help", ( - ("Shift+Alt", "sk_show_shortcuts"), + ("Shift-Alt", "sk_show_shortcuts"), )), ) def _mac_translate(keys: str) -> str: """Render a Ctrl/Alt/Shift spec with macOS symbols, honouring Qt's - Ctrl↔Cmd swap (the app's 'Ctrl' is the ⌘ key on macOS).""" + Ctrl↔Cmd swap (the app's 'Ctrl' is the ⌘ key on macOS). + + Hyphens are kept between every part, matching the non-Mac labels — + see the module docstring for why we do not use Apple's tight ⌘O. + """ s = keys - s = s.replace("Ctrl+Shift+", "⇧⌘") # macOS modifier order: ⇧ before ⌘ - s = s.replace("Shift+Alt", "⌥⇧") - s = s.replace("Ctrl+", "⌘") - s = s.replace("Alt+", "⌥") - s = s.replace("Shift + ", "⇧ ") + s = s.replace("Ctrl-Shift-", "⇧-⌘-") # macOS modifier order: ⇧ before ⌘ + s = s.replace("Shift-Alt", "⌥-⇧") + s = s.replace("Ctrl-", "⌘-") + s = s.replace("Alt-", "⌥-") + s = s.replace("Shift-", "⇧-") if s == "Shift": s = "⇧" return s