Skip to main content

Lightweight photo and video viewer with editing, PDF export and plugins.

Project description

myImages

A lightweight desktop viewer, editor and converter for photos and videos, built with PySide6. It looks like a compact, dark, icon-driven gallery (a close cousin of the sibling myPhotos project) but adds a tool panel, inline image editing, PDF/GIF export and preview, duplicate finding, batch rename and a plugin system.

The runtime core is deliberately tiny — PySide6 + Pillow. Everything else (ffmpeg for video, trash support, HEIC) is optional and can be installed from inside the app.

Features

  • Browse a folder, optionally including its sub-folders. The list keeps itself up to date when files are added, deleted or edited by other programs, and only the thumbnails that actually changed are rebuilt.
  • Preview photos with fit / wheel-zoom / pan, and videos with Qt Multimedia (falls back to a note + the video tools when the backend is absent).
  • Navigate with ←/→ or the mouse wheel; Shift+wheel zooms and never zooms out past the fit-to-window size.
  • File list on a panel that can sit on either side: three views (thumbnail grid, plain names, or a sortable table with clickable headers), a name-search box, favourites (F, shown as a star), and multi-select. Its width is set in whole thumbnail columns — one to four — so the grid always fills the panel instead of leaving a ragged strip of empty space.
  • Edit images inline under the preview (double-click a thumbnail, or the pencil icon): rotate, mirror horizontally or vertically, pick an aspect ratio that locks the crop box, Crop, then Save (overwrite) or Save as Copy; plus format conversion (JPEG/PNG/WebP/BMP/TIFF/GIF) and colour → black & white.
  • Remove a watermark: the badge generators stamp into a corner is detected and painted over with its surroundings. Draw a selection first to clean a mark anywhere else. The result opens in the editor, so nothing is written until you approve it.
  • Right-click a photo or a thumbnail for Copy File, Copy Filename, Copy Picture, Delete, Rename, Select, Edit Image, Rotate, Convert and Remove Watermark. Rename here renames that one file; the toolbar keeps the pattern-based batch rename for a whole selection.
  • Images → PDF: combine a selection into one PDF with control over page quality, maximum edge and greyscale, plus an optional target file size the builder meets by lowering quality automatically.
  • Video tools (via ffmpeg): trim on a timeline, crop the sides, scale, and export a GIF of the trimmed range.
  • GIF from frames: build an animated GIF from several selected images.
  • Find duplicates: exact (content hash) and visually similar (perceptual hash, adjustable) with one-click bulk delete of the extras.
  • Batch rename with a filename mask and a live preview (one file at a time is the plain box on the right-click menu).
  • Delete to the system trash when Send2Trash is installed.
  • Plugins: drop a *.py viewer into the plugins folder to preview new file types (a 3D-model example ships in myimages/plugins/).
  • Themes (dark/light), remembered layout, on-disk thumbnail cache.
  • Desktop integration (Settings → Desktop): add myImages to the application menu and make it the default for the photo and video types it opens. Both install into your own ~/.local/share, need no root, and can be undone from the same place. Opening a photo from a file manager loads its whole folder, so you can step through the gallery from there.

Run from source

Requires Python 3.10+ and (for video features) ffmpeg on the PATH.

python3 -m venv .venv && source .venv/bin/activate
pip install -e .
python main.py          # or: myimages

main.py in the repository root is just a thin shell around myimages.app.main; all the real code lives in the myimages package.

Pressing Ctrl+C in the launching terminal closes the app the normal way, so the window layout and settings are still saved on the way out.

Optional features

Open Optional features (the puzzle icon) in the app to see what is missing and install the Python ones (Send2Trash, pillow-heif) with a click. ffmpeg is a system tool — install it with your package manager:

sudo apt install ffmpeg

Develop

pip install -e ".[dev,trash,heif]"
pre-commit install
make check          # ruff + mypy + pytest (>90% coverage gate)

Individual gates: make lint, make typecheck, make test, make format.

The code style is strict on purpose: ruff, black, mypy --strict, self-documenting names (no leading-underscore identifiers) and a docstring on every public function. The pure logic (imaging, video, scanning, dedup, rename) is fully unit-tested; the PySide6 UI is tested offscreen with pytest-qt.

Build a package

make deb        # -> myimages_<ver>_<arch>.deb   (bundled venv under /opt/myimages)
make appimage   # -> myImages-<ver>-x86_64.AppImage

Both stage a self-contained virtualenv, add a launcher, the .desktop file and a rendered icon. See packaging/ for the scripts.

Project layout

Path Purpose
main.py Shell entry point (python main.py)
myimages/app.py QApplication bootstrap: logging, theme, plugins
myimages/config.py JSON-backed settings model
myimages/theme.py, icons.py Dark/light theme and painted vector icons
myimages/core/ Media model, scanning, thumbnails, dedup, rename, deletion, folder watching, plugins, dependencies
myimages/imaging/ Convert, transform (crop/scale/rotate/grey), PDF
myimages/video/ ffmpeg wrapper, trim, crop/scale, GIF
myimages/gui/ PySide6 window, panels, viewers and tool dialogs
myimages/plugins/ Bundled example plugins (3D model info)
tests/ Pytest suite (offscreen, synthetic assets)
packaging/ .deb / AppImage build scripts and .desktop

See the roadmap for the plugin API and planned work.

Storage

Everything the app persists lives under ~/.myimages/:

  • settings.json — all preferences and favourites,
  • thumbnails/ — the on-disk thumbnail cache,
  • plugins/ — drop your own *.py viewer plugins here.

Point MYIMAGES_DATA_DIR elsewhere to relocate all of it (the test suite uses this to stay isolated).

Watching the folder

While a folder is open the app follows changes made to it elsewhere. A check reads the directory listing only — never the pictures — so it stays cheap: a folder of 3 000 photos (428 MB) costs about 114 ms per check, on a worker thread, every 10 s by default. The operating system also reports changes instantly, so the timer is only a safety net for network shares.

Optionally (Settings → Also verify file checksums) a handful of files per check are also md5-summed. That catches a file rewritten without changing its size or date, which no amount of stat-ing can see. Only a small rotating batch is hashed per pass, so the whole folder is still covered over time without ever re-reading every photo at once — hashing 3 000 photos in one pass would cost roughly 0.9 s and 428 MB of reads.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

myimages-0.0.1.tar.gz (179.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

myimages-0.0.1-py3-none-any.whl (122.7 kB view details)

Uploaded Python 3

File details

Details for the file myimages-0.0.1.tar.gz.

File metadata

  • Download URL: myimages-0.0.1.tar.gz
  • Upload date:
  • Size: 179.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for myimages-0.0.1.tar.gz
Algorithm Hash digest
SHA256 545395f9327ae4f9ddfa46b16b64c6b911f728ae8092e60a3dc8c5a0b1f3daa7
MD5 61bb529dcd92f76ffaf59c0650b927ac
BLAKE2b-256 7191f9f7dcdde7decaa0d2d8e3d4831986a90fb5e0d11676487c519b1424b4a1

See more details on using hashes here.

Provenance

The following attestation bundles were made for myimages-0.0.1.tar.gz:

Publisher: publish.yml on wachawo/myImages

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file myimages-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: myimages-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 122.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for myimages-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 397f02dde176ffb4b0528ce213594b5cbe588bc80dbf189a22ee6c8ab20820fc
MD5 533ad7a7673b4e0f7a28dbb287d82750
BLAKE2b-256 e8532954091b3f7f5cf4b697040c4fe4ab8f6d09d3f81f6ea1f08868b0be9e40

See more details on using hashes here.

Provenance

The following attestation bundles were made for myimages-0.0.1-py3-none-any.whl:

Publisher: publish.yml on wachawo/myImages

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page