-
Notifications
You must be signed in to change notification settings - Fork 0
v2.0: working engine, rebuilt UI #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
DhakadG
wants to merge
3
commits into
main
Choose a base branch
from
v2
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 2 commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| name: Build | ||
|
|
||
| on: | ||
| push: | ||
| branches: ["main"] | ||
| pull_request: | ||
| workflow_dispatch: | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| cache: pip | ||
| # The engine has no UI imports, so it tests without a display. | ||
| - run: pip install Pillow piexif | ||
| - run: python tests/test_engine.py | ||
|
|
||
| smoke: | ||
| needs: test | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| os: [macos-14, windows-latest] | ||
| runs-on: ${{ matrix.os }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| cache: pip | ||
| - run: pip install -r requirements.txt | ||
| # Proves the GUI actually constructs on this OS — imports, fonts, theme | ||
| # tokens, widget options — rather than only that the engine passes. | ||
| - run: python main.py --check | ||
| - run: python tests/test_gui_boot.py | ||
|
|
||
| macos-app: | ||
| needs: smoke | ||
| strategy: | ||
| fail-fast: false | ||
| matrix: | ||
| include: | ||
| # py2app bundles the running interpreter, so a single runner produces | ||
| # a single-arch app that will not launch on the other kind of Mac. | ||
| # macos-15-intel is the current Intel label; macos-13 was retired and | ||
| # a job targeting it queues forever instead of failing. | ||
| - runner: macos-15-intel | ||
| arch: intel | ||
| - runner: macos-14 | ||
| arch: apple-silicon | ||
| runs-on: ${{ matrix.runner }} | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| - uses: actions/setup-python@v5 | ||
| with: | ||
| python-version: "3.12" | ||
| cache: pip | ||
| - run: | | ||
| pip install -r requirements.txt | ||
| pip install py2app | ||
| # v1's workflow cd'd into a folder that was never in the repo, so this | ||
| # job had never once produced a bundle. | ||
| - run: python setup.py py2app | ||
| - name: Verify the bundle launches | ||
| run: | | ||
| APP="dist/WebP Studio.app" | ||
| test -d "$APP" || { echo "no bundle produced"; exit 1; } | ||
| file "$APP/Contents/MacOS/WebP Studio" | ||
| # Headless runners have no window server, so a full launch can't be | ||
| # tested here — confirm the embedded interpreter starts and imports. | ||
| "$APP/Contents/MacOS/WebP Studio" --check | ||
| - run: ditto -c -k --keepParent "dist/WebP Studio.app" "WebP-Studio-macOS-${{ matrix.arch }}.zip" | ||
| - uses: actions/upload-artifact@v4 | ||
| with: | ||
| name: WebP-Studio-macOS-${{ matrix.arch }} | ||
| path: WebP-Studio-macOS-${{ matrix.arch }}.zip | ||
| retention-days: 14 | ||
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,42 +1,8 @@ | ||
| # Python | ||
| __pycache__/ | ||
| *.py[cod] | ||
| *$py.class | ||
| *.so | ||
| .Python | ||
| build/ | ||
| develop-eggs/ | ||
| dist/ | ||
| downloads/ | ||
| eggs/ | ||
| .eggs/ | ||
| lib/ | ||
| lib64/ | ||
| parts/ | ||
| sdist/ | ||
| var/ | ||
| wheels/ | ||
| share/python-wheels/ | ||
| *.egg-info/ | ||
| .installed.cfg | ||
| *.egg | ||
| MANIFEST | ||
|
|
||
| # Virtual Environment | ||
| venv/ | ||
| env/ | ||
| ENV/ | ||
| .env | ||
|
|
||
| # PyInstaller/py2app | ||
| *.spec | ||
| .app/ | ||
| build/ | ||
| dist/ | ||
|
|
||
| # MacOS | ||
| .venv/ | ||
| .DS_Store | ||
|
|
||
| # IDEs | ||
| .vscode/ | ||
| .idea/ |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,100 +1,163 @@ | ||
| # ConvertImagesToWebP - MacAlpha v0.1 | ||
| # WebP Studio 2.0 | ||
|
|
||
| A native macOS GUI application for converting images to WebP format. | ||
| Batch image converter for macOS, Windows and Linux. Drop a folder, pick a | ||
| preset, get smaller images. | ||
|
|
||
| ## Features | ||
| A rewrite of ConvertImagesToWebP-MacAlpha v0.1 — same idea, working engine. | ||
|
|
||
| - 🖱️ **Drag & Drop** - Drop images or folders directly onto the app | ||
| - ⚙️ **Customizable Settings** - Quality, resolution, encoding speed | ||
| - 📊 **Real-time Progress** - Watch your conversions in progress | ||
| - 📈 **Size Savings Stats** - See how much space you saved | ||
| - 🌙 **Dark Mode Support** - Native macOS appearance | ||
| --- | ||
|
|
||
| ## Supported Formats | ||
| ## What's new in 2.0 | ||
|
|
||
| **Things v0.1 advertised but didn't do** | ||
|
|
||
| | | v0.1 | 2.0 | | ||
| |---|---|---| | ||
| | Drag & drop | `tkinterdnd2` in requirements, never imported | works; the app tells you if the package is missing | | ||
| | "Preserve EXIF & color profiles" toggle | ignored — metadata dropped from every file | actually written, plus optional GPS-only removal | | ||
| | `MAX_THREADS: 8` | unused; conversion ran one file at a time | real thread pool, auto-sized to your CPU | | ||
| | Time remaining | permanently "Calculating…" | live ETA and images/sec | | ||
| | Cancel | stopped, then reported "Conversion Complete!" | reports what finished and what never started | | ||
| | Errors | recorded, never displayed | listed on screen and savable to a log | | ||
| | 5,000-image batches | one widget per file, frozen window | single capped log view | | ||
| | `python setup.py py2app` | failed — missing `assets/icon.icns` | builds without an icon | | ||
| | GitHub Actions build | `cd` into a folder that isn't in the repo | fixed | | ||
|
|
||
| **New** | ||
|
|
||
| - **Output formats** — WebP, AVIF, JPEG, PNG (only the ones your Pillow build can write are offered) | ||
| - **Presets** — Web · Balanced · Archive · Smallest | ||
| - **Resize by** longest edge, width, height, or megapixels. Never upscales. | ||
| - **Destination control** — subfolder, a folder you choose, or next to each original | ||
| - **If a file already exists** — skip, overwrite, or rename | ||
| - **Preflight** — "482 images · 3.1 GB → Pictures/Converted" before you commit | ||
| - **Lossless mode**, encoder-effort control, worker count | ||
| - **System / Light / Dark**, remembered between launches | ||
| - **Keyboard** — `Ctrl/⌘O` folder · `Ctrl/⌘⇧O` files · `Return` convert · `Esc` stop or clear | ||
|
|
||
| - JPEG (.jpg, .jpeg) | ||
| - PNG (.png) | ||
| - BMP (.bmp) | ||
| - TIFF (.tiff, .tif) | ||
| - HEIC (.heic) | ||
| - WebP (.webp) - direct copy | ||
| --- | ||
|
|
||
| ## Installation | ||
| ## Install | ||
|
|
||
| ### 1. Prerequisite: Homebrew | ||
| ```bash | ||
| pip install -r requirements.txt | ||
| python main.py | ||
| ``` | ||
|
|
||
| If you don't have Homebrew installed, open Terminal and run: | ||
| Only `customtkinter` and `Pillow` are required. The rest are optional and the | ||
| app degrades cleanly without them — check what you have: | ||
|
|
||
| ```bash | ||
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | ||
| python main.py --check | ||
| ``` | ||
|
|
||
| ### 2. Setup Python & Dependencies | ||
| | Optional | Enables | | ||
| |---|---| | ||
| | `tkinterdnd2` | drag & drop onto the window | | ||
| | `piexif` | removing GPS tags while keeping the rest of the EXIF | | ||
| | `pillow-heif` | reading iPhone `.heic` / `.heif` | | ||
|
|
||
| ## macOS | ||
|
|
||
| Run these commands one by one in Terminal: | ||
| **Use Homebrew's Python, not Apple's.** macOS ships Tk 8.5.9; CustomTkinter | ||
| needs 8.6+ and renders as black rectangles below that. `python main.py --check` | ||
| prints your Tk version and says so if it's too old. | ||
|
|
||
| ```bash | ||
| # Install Python and Tkinter via Homebrew | ||
| brew install python python-tk | ||
| /opt/homebrew/bin/python3 -m venv venv && source venv/bin/activate | ||
| pip install -r requirements.txt | ||
| python main.py | ||
| ``` | ||
|
|
||
| # Navigate to the app folder | ||
| cd ConvertImagesToWebP-MacAlpha | ||
| ### Build a .app | ||
|
|
||
| # Create a virtual environment (fixes 'pip' issues) | ||
| python3 -m venv venv | ||
| ```bash | ||
| python setup.py py2app # -> dist/WebP Studio.app | ||
| ``` | ||
|
|
||
| # Activate the virtual environment | ||
| source venv/bin/activate | ||
| Drop an `assets/icon.icns` in first if you want a custom icon — unlike v1, the | ||
| build no longer fails without one. | ||
|
|
||
| # Install required libraries | ||
| pip install -r requirements.txt | ||
| **py2app bundles the interpreter it is run with, so the result is single-arch.** | ||
| An app built on an M-series Mac will not launch on an Intel Mac and vice versa. | ||
| CI therefore builds both (`macos-13` Intel, `macos-14` Apple Silicon) and | ||
| uploads them as separate artifacts. To produce one universal binary instead, | ||
| build with a universal2 python.org interpreter rather than a Homebrew one. | ||
|
|
||
| `LSMinimumSystemVersion` is set to 10.13, but the real floor is whatever the | ||
| building Python supports. | ||
|
|
||
| ### "The app is damaged and can't be opened" | ||
|
|
||
| That is Gatekeeper, not a broken build — the bundle is unsigned and | ||
| un-notarized, and anything downloaded from a browser or CI artifact gets | ||
| quarantined. Either right-click → Open the first time, or: | ||
|
|
||
| ```bash | ||
| xattr -dr com.apple.quarantine "/Applications/WebP Studio.app" | ||
| ``` | ||
|
|
||
| ### 3. Run the App | ||
| Signing and notarizing requires a paid Apple Developer account; that is the | ||
| only real fix for distributing to other people. | ||
|
|
||
| ## Tests | ||
|
|
||
| ```bash | ||
| python main.py | ||
| python tests/test_engine.py # no display needed | ||
| python tests/test_gui_boot.py # needs a display | ||
| ``` | ||
|
|
||
| ### Build .app Bundle (via GitHub Actions) | ||
| No framework. `test_engine` covers sizing math, alpha flattening, metadata | ||
| keep/strip, output-collision handling, the skip/overwrite/rename policies, | ||
| error isolation, cancel, and savings accounting. `test_gui_boot` builds the | ||
| real window and drives a real conversion through the Tk event loop — it exists | ||
| to catch what only breaks on a specific OS (fonts that don't resolve, widget | ||
| options a platform's Tk rejects) and runs in CI on macOS and Windows. | ||
|
|
||
| **Since you are on Windows**, you cannot build the macOS app directly. Instead: | ||
| Both write settings to a temp directory via `WEBP_STUDIO_CONFIG_DIR`, so they | ||
| never touch your real config. | ||
|
|
||
| 1. Push this code to a GitHub repository | ||
| 2. Go to the **Actions** tab in your repo | ||
| 3. Select **Build macOS App** workflow | ||
| 4. Run workflow (or it runs on push) | ||
| 5. Download the `MacOS-App-Bundle` artifact when done | ||
| --- | ||
|
|
||
| ### Build .app Bundle (on macOS) | ||
| ## How it works | ||
|
|
||
| ```bash | ||
| python setup.py py2app | ||
| ``` | ||
| main.py entry point + dependency check | ||
| core/ | ||
| config.py Settings dataclass, presets, JSON persistence | ||
| imaging.py one image: open → orient → resize → square → encode | ||
| runner.py scan, plan destinations, thread pool, cancel, progress | ||
| gui/ | ||
| theme.py design tokens — every color is a (light, dark) pair | ||
| widgets.py Card, StatTile, ProgressRing, SliderRow, LogView | ||
| panel.py the settings panel | ||
| screens/ home · progress · results | ||
| ``` | ||
|
|
||
| This creates `ConvertImagesToWebP.app` in the `dist/` folder. | ||
| `core/` has no UI imports, so the engine is usable from a script and testable | ||
| without a display. | ||
|
|
||
| ## Usage | ||
| ### Notes on behaviour | ||
|
|
||
| 1. **Drop Zone** - Drag images/folders or click Browse | ||
| 2. **Settings** - Adjust quality, resolution, encoding options | ||
| 3. **Progress** - Watch real-time conversion progress | ||
| 4. **Results** - View stats and open output folder | ||
| - **Resizing never upscales.** A limit larger than the source is a no-op. | ||
| - **Metadata off converts to sRGB.** An untagged file is read as sRGB by every | ||
| viewer, so baking the profile in keeps colors from shifting. | ||
| - **The output folder is excluded from scans.** Converting the same folder | ||
| twice will not re-convert its own results. | ||
| - **Failed files leave nothing behind.** A partial write is deleted, because a | ||
| truncated image looks fine in a file manager and fails later. | ||
| - **Animated sources take frame one**, and say so in the log. | ||
|
|
||
| ## Settings | ||
| ## Verified on | ||
|
|
||
| | Setting | Description | Default | | ||
| | ----------- | -------------------------- | -------- | | ||
| | Quality | WebP quality (1-100) | 90 | | ||
| | Resolution | Max megapixels limit | 19 MP | | ||
| | Encoding | Speed vs compression (1-6) | 6 (Best) | | ||
| | Metadata | Preserve EXIF/ICC profiles | Yes | | ||
| | Square Mode | Original, Crop, or Canvas | Original | | ||
| | | Status | | ||
| |---|---| | ||
| | Windows 11 · Python 3.12 · Tk 8.6 · CustomTkinter 6.0 | both test suites pass; app driven end to end | | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
| | Engine logic (any OS) | 12 checks, no display required | | ||
| | macOS | **not yet run** — no Mac available to the author. Push to `main` and the CI matrix will build and smoke-test Intel and Apple Silicon bundles. | | ||
| | Linux | should work; `test_gui_boot` needs `xvfb` in CI | | ||
|
|
||
| ## License | ||
|
|
||
| MIT License - Feel free to modify and distribute. | ||
|
|
||
| --- | ||
|
|
||
| Made with ❤️ for macOS | ||
| MIT. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| # Core processing engine | ||
| """Conversion engine: settings, single-image pipeline, batch runner.""" |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.