Tool for processing film negatives.
914
stars
750
commits
Python
primary language
Sep 9, 2026
updated
NegPy is a tool for processing film negatives. I built it because I wanted something made specifically for film scans that goes beyond a simple inversion tool. It simulates how film and photographic paper work but also throws in some lab-scanner conveniences.
It is built with Python, running natively on Linux, macOS, and Windows.

Click here to read the USER_GUIDE.md — A complete walkthrough of the NegPy workflow, features, and controls.
Conversion & Film Science
Capture & Input
Editing
Color & Output
Workflow & Data
Read about the math and the pipeline here
Grab the latest release for your OS from the Releases Page.
After that NegPy keeps itself current: when a new release is out, the left panel shows an ⬇ Update Available link that downloads and installs it for you, then reopens on the new version. No manual download, uninstall or reinstall.
I provide an .AppImage. Make it executable using chmod +x and It should just work.
Scanner support requires SANE to be installed on your system:
sudo apt install libsane # Debian/Ubuntu
sudo pacman -S sane # Arch
Or your distro's equivalent. The app launches fine without so you can ignore that if you don't plan to use a scanner.
Camera scanning support (optional) uses python-gphoto2 for tethered capture, and may need the system libgphoto2 installed:
sudo pacman -S libgphoto2 # Arch
Or look up your distro's equivalent package.
You can run NegPy directly via:
nix run github:marcinz606/NegPy
Or add it as an input to your own flake:
{
inputs.negpy.url = "github:marcinz606/NegPy";
outputs = { self, nixpkgs, negpy, ... }: {
# negpy.packages.<system>.default
};
}
Since this is a free hobby project, I don't pay Apple or Microsoft ransom for their developer certificates. You'll get a scary warning the first time you run it.
macOS:
.dmg file & drag the app to /Applications.xattr -cr /Applications/NegPy.app (this gets rid of the warning).If you build the DMG yourself on macOS, set NEGPY_MACOS_ARCH=x86_64 for an Intel build or NEGPY_MACOS_ARCH=arm64 for Apple Silicon.
Scanner support requires SANE via Homebrew:
brew install sane-backends
The app launches fine without so you can ignore that if you don't plan to use a scanner.
Camera scanning support (optional) uses python-gphoto2, and may need libgphoto2 from Homebrew:
brew install libgphoto2
Windows:
Scanner support (Plustek OpticFilm) — 8200i SE and 8100 V2 — uses the optional pyopticfilm driver (uv sync --group plustek or pip install negpy[plustek]). Bind the scanner to WinUSB with Zadig (replace the vendor/SilverFast driver; 07b3:1825 for the 8200i SE, 07b3:1824 for the 8100 V2). Windows release builds bundle pyopticfilm, PyUSB, and libusb. See docs/PLUSTEK_WINDOWS.md. Camera scanning is still unavailable on Windows (libgphoto2 has no Windows build).
You can also clone the repo and build it yourself, instruction here: CONTRIBUTING.md
Everything lives in your Documents/NegPy folder:
edits.db: Your edits.settings.db: Global settings like last used export settings or preview size.cache/: Thumbnails (safe to delete).export/: Default export location.icc/: Drop your paper/printer profiles here.override.toml: Startup overrides — see Troubleshooting / override.toml below.If NegPy crashes on startup or has rendering issues, edit Documents/NegPy/override.toml. It is created automatically on first run with sensible defaults for your OS. The [performance] numbers are also in Preferences (Ctrl + ,); a value in this file wins over the dialog, which is what makes it usable when the app will not start.
[rendering]
# Options: "auto", "vulkan" (Linux/Win), "dx12" (Win), "metal" (macOS), "cpu"
backend = "vulkan"
[display]
# Qt scene-graph backend. Options: "auto", "vulkan", "d3d12", "metal", "opengl", "software"
qt_rhi_backend = "auto"
# Window system plugin (Linux only). Options: "auto", "xcb", "wayland"
qt_platform = "auto"
[performance]
# Cap GPU texture size in pixels — useful on low-VRAM cards. "auto" = no limit.
max_texture_size = "auto"
# Force HQ preview on/off. Uncomment to override saved preference.
# force_hq_preview = false
# Long edge of the interactive preview in pixels (512-8192). Higher is a sharper
# canvas and more VRAM per frame.
# preview_render_size = 1600
# Preview cache size — keeps recently-viewed photos in memory for instant navigation.
# Lower these on low-RAM machines. Uncomment to override defaults (~1.2 GB / 8 photos).
# preview_cache_max_bytes = 1200000000
# preview_cache_max_entries = 8
[logging]
# "debug", "info", "warning", "error"
level = "info"
Setting backend = "cpu" disables GPU acceleration entirely — useful if the GPU backend crashes on your hardware.
Things I want to add later: ROADMAP.md
Check CONTRIBUTING.md for details.
Copyleft under GPL-3.
If you like this tool, maybe buy me a roll of film so I have more test data :)
(top 30 of 35)
Python
98.4%
WGSL
1.4%
Tool for processing film negatives.
914
stars
750
commits
Python
primary language
Sep 9, 2026
updated
NegPy is a tool for processing film negatives. I built it because I wanted something made specifically for film scans that goes beyond a simple inversion tool. It simulates how film and photographic paper work but also throws in some lab-scanner conveniences.
It is built with Python, running natively on Linux, macOS, and Windows.

Click here to read the USER_GUIDE.md — A complete walkthrough of the NegPy workflow, features, and controls.
Conversion & Film Science
Capture & Input
Editing
Color & Output
Workflow & Data
Read about the math and the pipeline here
Grab the latest release for your OS from the Releases Page.
After that NegPy keeps itself current: when a new release is out, the left panel shows an ⬇ Update Available link that downloads and installs it for you, then reopens on the new version. No manual download, uninstall or reinstall.
I provide an .AppImage. Make it executable using chmod +x and It should just work.
Scanner support requires SANE to be installed on your system:
sudo apt install libsane # Debian/Ubuntu
sudo pacman -S sane # Arch
Or your distro's equivalent. The app launches fine without so you can ignore that if you don't plan to use a scanner.
Camera scanning support (optional) uses python-gphoto2 for tethered capture, and may need the system libgphoto2 installed:
sudo pacman -S libgphoto2 # Arch
Or look up your distro's equivalent package.
You can run NegPy directly via:
nix run github:marcinz606/NegPy
Or add it as an input to your own flake:
{
inputs.negpy.url = "github:marcinz606/NegPy";
outputs = { self, nixpkgs, negpy, ... }: {
# negpy.packages.<system>.default
};
}
Since this is a free hobby project, I don't pay Apple or Microsoft ransom for their developer certificates. You'll get a scary warning the first time you run it.
macOS:
.dmg file & drag the app to /Applications.xattr -cr /Applications/NegPy.app (this gets rid of the warning).If you build the DMG yourself on macOS, set NEGPY_MACOS_ARCH=x86_64 for an Intel build or NEGPY_MACOS_ARCH=arm64 for Apple Silicon.
Scanner support requires SANE via Homebrew:
brew install sane-backends
The app launches fine without so you can ignore that if you don't plan to use a scanner.
Camera scanning support (optional) uses python-gphoto2, and may need libgphoto2 from Homebrew:
brew install libgphoto2
Windows:
Scanner support (Plustek OpticFilm) — 8200i SE and 8100 V2 — uses the optional pyopticfilm driver (uv sync --group plustek or pip install negpy[plustek]). Bind the scanner to WinUSB with Zadig (replace the vendor/SilverFast driver; 07b3:1825 for the 8200i SE, 07b3:1824 for the 8100 V2). Windows release builds bundle pyopticfilm, PyUSB, and libusb. See docs/PLUSTEK_WINDOWS.md. Camera scanning is still unavailable on Windows (libgphoto2 has no Windows build).
You can also clone the repo and build it yourself, instruction here: CONTRIBUTING.md
Everything lives in your Documents/NegPy folder:
edits.db: Your edits.settings.db: Global settings like last used export settings or preview size.cache/: Thumbnails (safe to delete).export/: Default export location.icc/: Drop your paper/printer profiles here.override.toml: Startup overrides — see Troubleshooting / override.toml below.If NegPy crashes on startup or has rendering issues, edit Documents/NegPy/override.toml. It is created automatically on first run with sensible defaults for your OS. The [performance] numbers are also in Preferences (Ctrl + ,); a value in this file wins over the dialog, which is what makes it usable when the app will not start.
[rendering]
# Options: "auto", "vulkan" (Linux/Win), "dx12" (Win), "metal" (macOS), "cpu"
backend = "vulkan"
[display]
# Qt scene-graph backend. Options: "auto", "vulkan", "d3d12", "metal", "opengl", "software"
qt_rhi_backend = "auto"
# Window system plugin (Linux only). Options: "auto", "xcb", "wayland"
qt_platform = "auto"
[performance]
# Cap GPU texture size in pixels — useful on low-VRAM cards. "auto" = no limit.
max_texture_size = "auto"
# Force HQ preview on/off. Uncomment to override saved preference.
# force_hq_preview = false
# Long edge of the interactive preview in pixels (512-8192). Higher is a sharper
# canvas and more VRAM per frame.
# preview_render_size = 1600
# Preview cache size — keeps recently-viewed photos in memory for instant navigation.
# Lower these on low-RAM machines. Uncomment to override defaults (~1.2 GB / 8 photos).
# preview_cache_max_bytes = 1200000000
# preview_cache_max_entries = 8
[logging]
# "debug", "info", "warning", "error"
level = "info"
Setting backend = "cpu" disables GPU acceleration entirely — useful if the GPU backend crashes on your hardware.
Things I want to add later: ROADMAP.md
Check CONTRIBUTING.md for details.
Copyleft under GPL-3.
If you like this tool, maybe buy me a roll of film so I have more test data :)
(top 30 of 35)
Python
98.4%
WGSL
1.4%