nkscan
A cross-platform and performant library and command line application for Nikon film scanners
Support
I only own a Coolscan 9000, but through reverse-engineering of the Nikon binaries and the work of others, we are slowly adding support for more scanners. Please reach out if you have a scanner we can test! Even just dumps of USB/SCSI payloads of a normal scan would be incredibly useful.
| Linux | Windows | |
|---|---|---|
| LS-9000 (Coolscan 9000) | Tested | Tested |
| LS-50 (Coolscan V) | Tested | Untested |
| LS-5000 (Coolscan 5000) | Untested | Untested |
MacOS support is planned, but just stubbed out for the moment.
Usage
Usage: nkscan [OPTIONS]
Options:
--device <DEVICE> Which scanner to use, as `--list` reports it. Only needed when more than one is attached
--list List the scanners attached and exit, without touching any of them
--frames <FRAMES> Frames on the loaded strip
--frame <FRAME> Which frames to actually scan, zero-indexed and comma separated. All of them by default
--dpi <DPI> Resolution in DPI. One of the firmware's divisions of the sensor's native pitch
--gain <R,G,B[,IR]> Fixed per-channel analog gain as `red,green,blue[,ir]`, which turns autoexposure off
--focus <FOCUS> Focus: `auto` to let the scanner find it on each frame, or a fixed setpoint [default: auto]
--ir Capture the infrared plane for dust removal
--basename <BASENAME> Where to write, as a path prefix. Each frame becomes <basename>_<n>.tiff, and its infrared mask <basename>_<n>_ir.tiff [default: scan]
--offset <OFFSET> Where each frame starts along the feed, in mm, comma separated, last value repeating
--pitch <PITCH> Frame pitch in mm, overriding what the scanner would use
--lock-wb Hold the white balance during autoexposure, so the film keeps its cast. Not on the LS-50
--multisample <MULTISAMPLE> Multisampling, trading scan time for noise. One of 1,2,4,8,16. LS-9000 only [default: 1]
--singleline Single-line CCD mode. Slow, but may improve banding. LS-9000 only
--eject Send the film back out when everything is done
--batch Scan every strip of the roll, ejecting and pausing to reload in between
-h, --help Print help (see more with '--help')
-V, --version Print version
Example Workflow
Raw Negatives for External Inversion
Say I have a LS-9000 and I invert with either NegPy or Negative Lab Pro. For this to work well, I want essentially the raw scans out of the scanner, but with equal exposure across all frames so I can perform "roll analysis".
So, I load up the film holder with the first strip (in my case 6x6 negatives, with three frames), and scan in "batch mode". For this, I tell the program how many frames per strip, include the IR pass, lock the whitebalance during autoexposure of the first frame (which will be applied to every farme), and enable 2x multisampling.
nkscan --frames 3 --ir --lock-wb --multisample 2 --batch
Personally, I find this much faster than anything I could do in NikonScan or Vuescan.
Python
We also ship the driver as a Python extension, which simplifies use in from Python-based scanning/inversion programs. The image data comes back as zero-copy numpy arrays in linear 16-bit ADC counts.
pip install nkscan
import nkscan
device = nkscan.list_devices()[0]
print(device.id, device.model, device.capabilities.dpi)
with nkscan.Session(device.id) as session:
# Three 6x6 frames at a 56 mm pitch, holding one exposure across all of them
session.prepare(frames=3, pitch_mm=56.0, gain=(283048, 202864, 166589))
for frame in range(3):
result = session.scan(frame, dpi=2000, ir=True,
progress=lambda read, total: print(f"\r{read}/{total}", end=""))
result.rgb # (height, width, 3) uint16
result.ir # (height, width) uint16, or None
session.eject()
The scan may take minutes, so a progress callback can drive a UI and returning False from it stops the scan.
Failures worth retrying share a nkscan.TransientError base, so one except covers a link glitch or a short read without swallowing a real problem like nkscan.MediaError.
Building it from source needs maturin; the dev shell in flake.nix has it, along with a Python carrying numpy.
maturin develop
The type stub is generated rather than written, so it cannot fall out of step with the bindings:
cargo run --features python --bin stub_gen
License
Dual licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE)
- MIT license (LICENSE-MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Related Projects and References
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file nkscan-0.1.0.tar.gz.
File metadata
- Download URL: nkscan-0.1.0.tar.gz
- Upload date:
- Size: 201.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
66d84dc1910b2d87ac270dcaf33ca249a44287cb691a77c5a789cbd8ee5cbee3
|
|
| MD5 |
ea872aea3457673161bc753a8a74fdfc
|
|
| BLAKE2b-256 |
1075be7781b46868cda43314ff98522a200a9d19b5ab20bb09e2155639042a2c
|
Provenance
The following attestation bundles were made for nkscan-0.1.0.tar.gz:
Publisher:
release.yml on activexray/nkscan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nkscan-0.1.0.tar.gz -
Subject digest:
66d84dc1910b2d87ac270dcaf33ca249a44287cb691a77c5a789cbd8ee5cbee3 - Sigstore transparency entry: 2292118826
- Sigstore integration time:
-
Permalink:
activexray/nkscan@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/activexray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nkscan-0.1.0-cp313-abi3-win_amd64.whl.
File metadata
- Download URL: nkscan-0.1.0-cp313-abi3-win_amd64.whl
- Upload date:
- Size: 401.0 kB
- Tags: CPython 3.13+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ec63b85d2b6aafe43e59a7e1ab460cd8b145f486335cd5d475b58f536d9e3389
|
|
| MD5 |
580558f1ec8ba6063d433594ccddd5c1
|
|
| BLAKE2b-256 |
b6a72f5a8dfef2b78e668b22de42ed115eb627f71d54cc1106b4b34d49a3b5b4
|
Provenance
The following attestation bundles were made for nkscan-0.1.0-cp313-abi3-win_amd64.whl:
Publisher:
release.yml on activexray/nkscan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nkscan-0.1.0-cp313-abi3-win_amd64.whl -
Subject digest:
ec63b85d2b6aafe43e59a7e1ab460cd8b145f486335cd5d475b58f536d9e3389 - Sigstore transparency entry: 2292119043
- Sigstore integration time:
-
Permalink:
activexray/nkscan@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/activexray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nkscan-0.1.0-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: nkscan-0.1.0-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 663.7 kB
- Tags: CPython 3.13+, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2fec70749cc876b665b3fac0d727fbbc36a7680c8bae6462919900ba1bbdbc92
|
|
| MD5 |
19e3ebed60ae1711e36bf764bcc2bbb5
|
|
| BLAKE2b-256 |
dfeea7aa7bc9208d18e3637590927974e5a74a0f9d2df35b24ebb4b97d4e2aa5
|
Provenance
The following attestation bundles were made for nkscan-0.1.0-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:
Publisher:
release.yml on activexray/nkscan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nkscan-0.1.0-cp313-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl -
Subject digest:
2fec70749cc876b665b3fac0d727fbbc36a7680c8bae6462919900ba1bbdbc92 - Sigstore transparency entry: 2292119003
- Sigstore integration time:
-
Permalink:
activexray/nkscan@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/activexray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nkscan-0.1.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: nkscan-0.1.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 615.4 kB
- Tags: CPython 3.13+, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4a7253339c4e9f9b5f6040b8b66bb50ae9d2a1786d7679a2ce71fc3dfeebfb44
|
|
| MD5 |
b3db51a9d1d4c7dc3eecdfa6a8ed144a
|
|
| BLAKE2b-256 |
48c633df56f628486f5c338375f806eb6efe2380a7e024e2aa7ad1ef8e27d006
|
Provenance
The following attestation bundles were made for nkscan-0.1.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl:
Publisher:
release.yml on activexray/nkscan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nkscan-0.1.0-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl -
Subject digest:
4a7253339c4e9f9b5f6040b8b66bb50ae9d2a1786d7679a2ce71fc3dfeebfb44 - Sigstore transparency entry: 2292118969
- Sigstore integration time:
-
Permalink:
activexray/nkscan@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/activexray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nkscan-0.1.0-cp313-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: nkscan-0.1.0-cp313-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 532.6 kB
- Tags: CPython 3.13+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
285350c5efee51e7fc56c6933ece863d83d1f1aa6f653052ddaae13e18f085d8
|
|
| MD5 |
2d057e69713052251eef0af4ebe101d5
|
|
| BLAKE2b-256 |
f95e8addcd41d8c60a10dfd43d5e0fab7b7266ce4564c56272997074f139ae94
|
Provenance
The following attestation bundles were made for nkscan-0.1.0-cp313-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on activexray/nkscan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nkscan-0.1.0-cp313-abi3-macosx_11_0_arm64.whl -
Subject digest:
285350c5efee51e7fc56c6933ece863d83d1f1aa6f653052ddaae13e18f085d8 - Sigstore transparency entry: 2292118877
- Sigstore integration time:
-
Permalink:
activexray/nkscan@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/activexray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Trigger Event:
push
-
Statement type:
File details
Details for the file nkscan-0.1.0-cp313-abi3-macosx_10_12_x86_64.whl.
File metadata
- Download URL: nkscan-0.1.0-cp313-abi3-macosx_10_12_x86_64.whl
- Upload date:
- Size: 549.1 kB
- Tags: CPython 3.13+, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f39fd98a02b6fb5d293c06febb56e8aa7ac94b0afb0e1b37e5846d5c31d99198
|
|
| MD5 |
ba45ec15300463de2c2039685dd7000a
|
|
| BLAKE2b-256 |
96fad7e5bec233f36746e687f1ce7444c159167aae4b7aea2435fc884cdf8906
|
Provenance
The following attestation bundles were made for nkscan-0.1.0-cp313-abi3-macosx_10_12_x86_64.whl:
Publisher:
release.yml on activexray/nkscan
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
nkscan-0.1.0-cp313-abi3-macosx_10_12_x86_64.whl -
Subject digest:
f39fd98a02b6fb5d293c06febb56e8aa7ac94b0afb0e1b37e5846d5c31d99198 - Sigstore transparency entry: 2292118927
- Sigstore integration time:
-
Permalink:
activexray/nkscan@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/activexray
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@51d45f38b6f3cf5caaaf10e0b758d4ebdccfc070 -
Trigger Event:
push
-
Statement type: