RIP & Encoder¶
paintress-rip-encoder provides the Python tools that turn an image into a
print job. The RIP prepares the dot patterns; the encoder packs them for the
firmware.
Source code: paintress-team/paintress-rip-encoder.
rip/rip.py, the raster image processor¶
Loads an image, converts it to CMYK (or CMYK plus light cyan and light magenta), applies dot-gain compensation, and halftones each channel with one of three dithering algorithms:
- Floyd–Steinberg error diffusion, the default,
- blue noise, higher quality, optional, needs
scipy, - ordered, with a Bayer matrix.
--head selects c6n90 or c4n180, which defines the channels, nozzle pitch
and band step. Use --ink-map to specify the ink connected to each slot.
The output is a RIP payload, a .json header with a packed .bin file,
holding every halftoned pass and a metadata block: DPI, dimensions, channel
order, per-pass Y positions, and the head layout the payload was made for.
DPI can be any multiple of the head's nozzle pitch, 90 npi on c6n90 and
180 on c4n180; --list-dpi prints the valid values.
Use rip.py --target to generate a calibration target without an input image:
wedge, nozzle_check or col_align. See RIP and
halftoning.
rip/viewer.py, inspection¶
The viewer renders a preview of the RIP payload before encoding. Its soft proof simulates drop spread to help inspect tone, grain, missing-nozzle streaks and band seams. It also estimates ink use in µL per channel.
encoder/encoder.py¶
The encoder reads the head layout from the RIP payload and converts the data
to the firmware wire format. It compensates for physical offsets between
nozzle columns, packs the buses into 147-byte lines and writes a .json job
header with a packed .bin file.
The job header carries two compatibility checks. The daemon compares
geometry_fingerprint with the firmware's frame fingerprint, and checks
head_name and head_fingerprint against its configured head. See File
formats and Printhead data
protocol.
tools/, calibration and bench¶
calibrate_from_scan.py builds the tone curves from a scan of the printed
wedge; it is the only automatic calibration. The other two targets are read
by eye: record_dead_nozzles.py stores the failed nozzles you read off the
nozzle check, and col_align_gaps.py turns the col_align readings into
encoder column gaps.
Dependencies¶
pillow and numpy, plus optionally numba (JIT) and scipy (blue
noise).
DPI, nozzles and passes¶
A band is built by combining passes_per_band interleaved swaths.
band_step_nozzles is the shortest plumbed slot, not the column length. See
Swaths and passes.