Fix a scan's colour cast with one button, clean up dust, crop and straighten, and keep every roll in one library.
RAW files too. No account, no subscription, and your photos never leave your computer.
English · 한국어
Lab scans often come back flat, and yellow, green or blue. Auto tone sets the black and white points of the picture. Auto Colour looks at the shadows, the midtones and the highlights separately and corrects each with channel curves, because a film scan is rarely off by the same amount everywhere. One white balance value cannot do that.
Left: the scans as they came from the lab. Right: after one press of Auto tone and one of Auto Colour, with no other adjustment.
- Photos lit by coloured light (a concert, a neon sign) are left alone.
- A strength slider sets how far the correction goes. A very strong cast does not come back completely.
- Tungsten film shot in daylight, or the other way round, has its own one-button conversion.
- Free and local. No account, no subscription, no usage statistics. Photos and edits stay on your computer, and your originals are never modified.
- Made for film scans. Negative conversion, Auto Colour, automatic detection of dust and scratches that you review before anything is removed, cropping of scan borders, grain.
- RAW development. 14 of 15 public RAW samples open: Canon, Nikon, Fujifilm (X-Trans), Leica, Sony, Panasonic, Olympus, Pentax, Ricoh. Nikon's High Efficiency (HE) compressed NEF does not.
- GPU acceleration. Direct3D 11 on Windows, Metal on macOS. On an M1 Pro, fully developing a 24 MP photo (with noise reduction and sharpening) took 8.2 s on the CPU alone and 1.6 s with acceleration (measured once). The accelerated result is within one 8-bit step of the CPU result.
- Lightroom catalogs. Imports Lightroom catalogs (ratings, flags, collections, develop settings) and presets.
Register a folder and new photos are imported as they appear. Organise with ratings, flags, colour labels, keywords, collections and smart collections.
Auto straighten finds the angle and puts it on the slider. Drag outside the frame to turn the photo; the crop frame follows so that no empty corner is left.
Exposure, tone and channel curves, an eight-colour mixer, colour grading, camera profiles (DCP) and lens corrections (Lensfun). Edits are recorded as you make them, with no Save button, and every step can be undone.
Select areas with a brush, linear and radial gradients, or colour and luminance ranges, and combine them by adding, subtracting and intersecting. Below, a linear gradient on the sky only.
Left: the RAW file as imported. Right: with basic adjustments and the sky mask above.
The film scans on this page are the author's own. The other photos are CC0 samples from raw.pixls.us (Leica M (Typ 240), Ricoh GR III, Canon EOS R5 and others). The screenshots were taken by driving the real program automatically.
- Download
Grainy-<version>-windows-x64.zipfrom Releases and unpack it wherever you like. - Run
Grainy.exe. - The program is not code-signed, so Windows shows an "unknown publisher" warning the first time.
- Windows 10/11, 64-bit.
- The library is created in
%LOCALAPPDATA%\Luma\Library.
- Download
Grainy-<version>-macos-arm64.dmgfrom Releases, open it and drag Grainy to the Applications folder. - On first start macOS blocks the app as coming from an unidentified developer. Press "Open Anyway" once in
System Settings → Privacy & Security. The app has no Apple developer signature or notarization.
- An Apple Silicon Mac (M1 or later) and macOS 14 or later. Intel Macs are not supported.
- The library and settings are created in
~/Library/Application Support/Grainy/. - 0.5.84 is the first macOS release. It passes the automated tests but has not been used on many people's Macs. Please report problems with the Feedback button.
- Windows: delete the unpacked Grainy folder. Nothing is written to the registry or system settings.
- To remove the edits as well, delete
%LOCALAPPDATA%\Luma(library) and%LOCALAPPDATA%\Grainy(settings). Your original photos are not in these folders. - macOS: move Grainy from the Applications folder to the Trash. To remove the edits as well, delete
~/Library/Application Support/Grainy.
- Library: import folders, automatic import of new photos in registered folders, ratings, colour labels and keywords, collections and smart collections, recovery of moved folders
- RAW development: RAW files of the major camera makers, camera profiles (DCP), lens corrections (Lensfun)
- Film negatives: one button turns a scanned negative into a positive (film base removed per channel); every other tool then works on the positive. A roll scanned with the same settings can be measured as one, so every frame is converted with the same colour reference
- Film looks: 82 named films (Kodak Portra, Ektar, Kodachrome, Tri-X, Vision3, Fujifilm Velvia, Provia, Acros, Ilford HP5, Delta and more), each computed from its maker's published technical data — spectral sensitivity, characteristic curves and dye densities — and printed on the paper it was made for (slides are viewed as they are), with an amount slider and the film's grain
- Adjustments: exposure, tone curve, channel curves, colour mixer, colour grading, auto tone, auto colour (colour-cast correction), film colour-temperature conversion (tungsten ↔ daylight), a choice of tone mapping (classic or smooth highlights), and an on/off switch on every panel
- Detail: sharpening, noise reduction, grain, vignette
- Local adjustments: masks (Select Sky, brush, linear and radial gradients, colour and luminance ranges, add / subtract / intersect), healing, dust removal
- Shortcuts: for the tools and masks (W, K, M, Shift+M, Q…), the view (F full screen, L lights out, Tab panels, Z 1:1, J clipping), auto tone and colour (Ctrl+U, Ctrl+Shift+U), rotation (Ctrl+[ ]) and colour labels (6–9); press ? for the list
- Export: JPEG, PNG, TIFF, AVIF, JPEG XL
- Feedback: a button at the top of the window sends a problem report or an idea
- Updates: the program checks for a new version and replaces itself
- AI connection: install Grainy's MCP once with one command in an AI program on this computer (Claude Code, Codex, Claude Desktop), and while Grainy is running that program can import, list, look at, rate, edit (presets, film looks, curves, copied settings, snapshots, virtual copies) and export your photos with Grainy's own tools; every AI edit or rating/label change is one batch you can undo
- Also: edit history and undo, Lightroom catalog and preset import, catalog backup (including a Google Drive folder), a GPS map
Learn it hands-on in your browser: pastorius9.github.io/grainy/learn. The full manual ships with the program (README.html, in Korean).
Click Ask AI in the header, choose an installed Claude Code, Codex or Gemini CLI, type a request, and press Send or Ctrl+Enter. The optional model field is empty for the program's default. Missing programs can be installed from this window using the vendor’s official installer, with the command shown before it runs. Each program uses its own account and subscription; the window shows each program’s sign-in status and can open its official sign-in, while Grainy never sees passwords or keys.
The non-modal window shows replies and Grainy tool calls while the photos update. Stop ends the program and its children; edits already applied remain. New conversation clears the conversation, and Undo Last AI Task uses the same batch undo as AI Connection. If the AI connection is off, the window offers to turn it on. No separate MCP installation is needed for this window.
Each request also says which folder is open in Grainy, which photos are selected and which photo is being edited, so "this folder" and "this photo" mean what you see. Claude Code continues its own session on a follow-up; that conversation stays in Claude Code's own history, as when you use Claude Code directly. Codex runs with session recording disabled and follow-ups receive up to the last three exchanges as text (the window says so). Gemini resumes its session, stored under Grainy's settings folder. The window itself keeps its transcript only in memory. Sending a request starts the chosen AI program, which sends what it reads to its own service; the first-use notice and AI Connection details explain the photo information it can read.
- No usage statistics are collected. Only two things go to the internet, and both only when you ask.
- Feedback: pressing Send transmits the text you typed, the Grainy version, a one-line system description (operating system version and graphics adapter name) and a random five-character reference number. The reference is also kept on your computer so that a later update can tell you when your feedback was addressed. Photos, file names and paths, and user names are not sent.
- Updates: the latest version information is read from GitHub only when you press "Check for Updates" or have switched on the automatic check (you are asked at first start, and it can be switched off in Settings). Nothing about you is sent.
- AI connection: the connection is on while Grainy runs (Settings › AI Connection (MCP) can switch it off), but nothing is read and nothing leaves the computer unless you send a request in Ask AI or install Grainy's MCP in an AI program on this computer and ask that program to work. It can then read the photo list and photo details: file names and full file and folder paths (which include your user name), keywords, ratings, camera, lens, exposure settings and capture date, but not GPS location. It can also read edit values and previews up to 1568 pixels, including contact sheets of up to 36 photos. It can change edit values, ratings, flags and color labels, save and restore snapshots and make virtual copies. It can import the photos of a folder it names into the library (the files are only read), and export copies into the AI export folder (Pictures/Grainy unless you change it), the folder of your last export, or any other folder on this computer it names except Grainy's own library, settings and program folders; existing files are never replaced. It can save contact-sheet JPEGs up to 4000 pixels to these same destinations. What it reads goes to that AI program's service under its own terms, and AI programs may keep their own copies, for example in conversation logs. Grainy itself never sends photos anywhere. The connection is open only on this computer and needs a key that Grainy keeps in plain text in its own settings folder; the installed MCP reads it from there, so the key is not put into the AI programs' configuration (unless you set up a direct HTTP connection under Advanced). Original files are never changed. AI edits and rating/flag/label changes can be undone, most recent first, for the last 5 AI tasks as long as their photos were not edited again; each photo the AI edits first also gets a "Before AI edits" snapshot. Imports, virtual copies, saved contact sheets and exported files are not part of that undo.
Grainy only has to be running. Install its MCP once in the AI program you use; the commands are the same on every computer and hold no key. Settings › AI Connection (MCP)… in Grainy shows them too, with Copy buttons. Run Grainy once first: it puts the bridge that these commands start into its own folder (%LOCALAPPDATA%\Grainy\mcp on Windows, ~/Library/Application Support/Grainy/mcp on macOS).
- Install it in the program you use:
- Claude Code, in PowerShell (Windows), then restart Claude Code and check with
claude mcp list:in Terminal (macOS):claude mcp add --scope user grainy '--' powershell -NoProfile -ExecutionPolicy Bypass -File "$env:LOCALAPPDATA\Grainy\mcp\grainy-mcp-bridge.ps1"
claude mcp add --scope user grainy -- sh "$HOME/Library/Application Support/Grainy/mcp/grainy-mcp-bridge.sh" - Codex, in PowerShell (Windows), then restart Codex and check with
codex mcp list:in Terminal (macOS):codex mcp add grainy '--' powershell -NoProfile -ExecutionPolicy Bypass -File "$env:LOCALAPPDATA\Grainy\mcp\grainy-mcp-bridge.ps1"
codex mcp add grainy -- sh "$HOME/Library/Application Support/Grainy/mcp/grainy-mcp-bridge.sh" - Claude Desktop: open Settings › Developer › Edit Config, put the
"grainy"entry inside"mcpServers"(if the file is empty, paste all of it) and restart Claude Desktop. Windows:macOS:{"mcpServers": {"grainy": {"command": "powershell", "args": ["-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", "& (Join-Path $env:LOCALAPPDATA 'Grainy\\mcp\\grainy-mcp-bridge.ps1')"]}}}{"mcpServers": {"grainy": {"command": "/bin/sh", "args": ["-c", "exec /bin/sh \"$HOME/Library/Application Support/Grainy/mcp/grainy-mcp-bridge.sh\""]}}}
- Claude Code, in PowerShell (Windows), then restart Claude Code and check with
- Ask, for example: "Show me roll 12 as a contact sheet, then invert the negatives as one roll and even out the exposure." Each change is one batch: ask the AI to undo it, or use Undo Last AI Task in Grainy's AI Connection window.
The AI can crop in the displayed orientation, auto straighten, detect scan borders, compare up to 12 film looks or presets without virtual copies, and set different ratings/flags/labels per photo in one undoable batch. It can save a contact-sheet JPEG up to 4000 pixels with file and look names. Export results list the first 100 output files with names, pixel dimensions and byte sizes (plus a remaining count); dry_run: true plans names and pixel dimensions without writing files, with byte sizes unknown until export. Preview sizes are upper limits and may shrink to fit response byte limits. After a Grainy update, start a new AI session: existing sessions keep the old tool list.
On Windows keep the quotes around '--': without them PowerShell drops the -- when claude or codex was installed with npm. The AI program may be started before Grainy. While Grainy is not running, or its AI connection is switched off, the program still lists Grainy's tools, and a call answers that Grainy is not running and how to fix it. Programs that connect over HTTP directly use the address and the key under Advanced in the same window; after New Key or Use Another Port set those up again, while programs installed as above keep working.
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt
.venv\Scripts\python main.pyThe C++ modules for GPU acceleration and colour conversion are built with tools/build_native_*.py (Visual Studio C++ tools on Windows; tools/build_native_macos.py with the Xcode command line tools on macOS). Run the tests with python tools/check.py: more than 1,200 of them.
Grainy's own code is under the MIT License. You may use, modify, redistribute and sell it, keeping the copyright notice and the license text. The name "Grainy" and the logo are not covered by the license.
Third-party components keep their own licenses: Qt/PySide6 (LGPL-3.0), LibRaw, OpenCV, Lensfun and others. The full list and terms are in DISTRIBUTION.md (Korean); the notices are in the THIRD_PARTY_LICENSES folder of a release.
Adobe, Lightroom and Photoshop are trademarks of Adobe Inc. Grainy is an independent project: it is not made, sponsored or endorsed by Adobe and is not affiliated with it.
Film and paper names (Kodak, Portra, Kodachrome, Fujifilm, Velvia, Ilford, HP5 and the others in the Film panel) are trademarks of their owners, among them Eastman Kodak Company, Kodak Alaris, FUJIFILM Corporation, Harman Technology, FOMA BOHEMIA, Agfa-Gevaert and CineStill. Grainy is not made, sponsored or endorsed by, or affiliated with, any of them; its film looks are simulations computed from their published technical data. The CIE colorimetric data they use is under CC BY-SA 4.0 (see THIRD_PARTY_LICENSES/Film).
Release binaries are not signed yet. This project has applied for free code signing for open source projects:
Free code signing provided by SignPath.io, certificate by SignPath Foundation.
- Committers and reviewers: pastorius9
- Approvers: pastorius9
- Only binaries built from this repository are signed. Third-party libraries shipped with Grainy keep their own publishers' signatures.
- Signed releases are built from source by GitHub Actions (build.yml) on a GitHub-hosted runner; the native libraries are compiled there as well.
Privacy policy: This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it. There are two such requests. The Feedback dialog: pressing Send transmits the text you typed, the Grainy version, a one-line system description (operating system version and graphics adapter name) and a random five-character reference number. Updates: "Check for Updates" and, only if you switch it on when asked at first start (it can be switched off in Settings), a once-a-day check at start-up read the latest release information from GitHub; installing an update downloads the release file from GitHub. Photos, file names, paths and user names are never transmitted.






