Film Rebate
Make a fake scan look like a scan
- image
- image
- image_area
The "rebate" is the dead space around a film frame - the sprocket holes, the edge numbers, the notch code on a 4x5 sheet, the white frame of a Polaroid. It's the detail that makes a flat digital image read as a scan of something physical, and almost nobody bothers to fake it properly. Film Rebate is Darkroom's node for that job, and it's a lot more than a white rectangle border.
It's procedural and format-correct: seven formats in one dropdown - 135 full frame, the 135 "filed carrier" look, 120 6x6 and 6x9, 4x5 sheet, Polaroid, and 35mm slide mount. Every dimension is computed from real millimeters, so it's resolution-independent by construction: run it at 512 or 4096 and the sprocket geometry stays proportionally correct.
How it works. The node composes your image into a larger film/print canvas (it extends the canvas, it doesn't crop), then draws the format's hardware around it. Two choices shape the whole output. format picks the geometry. film_type sets the rebate polarity - Color neg, B&W neg, or Reversal - which drives the border color; Polaroid and Slide use their own surface colors instead. Then compose decides how your image meets the aperture: fill cover-crops it in (the default), fit letterboxes it with rebate-color bars.
The details are where it gets fun. 135 full frame gives you KS-1870 perforations, the classic dual frame-numbering, and an optional stylized DX barcode (dx_barcode, plausible but not decodable - it's the look, not a real code). The filed carrier format is the Cartier-Bresson full-negative look: a seeded, jagged black border you can shape with border_width, roughness and paper_margin. 4x5 sheet prints an F-3-style notch code selected by stock name. And Polaroid - the author claims the dims were re-verified against Polaroid's own support figures, which is exactly the kind of obsessive detail the rest of this pack has.
Inputs you'll actually set:
format- the big one. Everything else is fine-tuning once you pick the frame.compose-fillvsfitfor the aspect mismatch between your image and the format aperture.frame_number- the first frame's edge-print number (135/120). Pair it withincrement_per_frameand a batch becomes a contact sheet with numbers counting up.stock_name- drives the edge print, the 4x5 notch pattern, and the slide-mount color. Defaults to "AKURATE 400".seed- seeds the filed-carrier perimeter noise and the DX barcode pattern.
Outputs. image, and image_area - a MASK of where your photo actually landed inside the border. That's the piece you want for compositing: darken or blur everything outside it to kill the "this is a rendered image pasted on a background" look, or feed it to an inpaint. On a slide mount, date_text stamps red-ish ink like "MAY 74" across the mount, which is absurd and I love it.
Install. ComfyUI Manager, search "Darkroom", or:
cd ComfyUI/custom_nodes/
git clone https://github.com/jeremieLouvaert/ComfyUI-Darkroom.git
pip install -r ComfyUI-Darkroom/requirements.txt
Restart and it's under AKURATE/Darkroom/Film. Only scipy and opensimplex required, no models, no keys. One note: background (the small scanner-surround margin outside the film edge) defaults to black - set it to white if you're faking a flatbed scan rather than a dark slide scan. The Polaroid format especially looks wrong against a black surround.
Inputs (16)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| formatopt | COMBO | 135 full frame | Film/print format geometry. Drives every mm-derived dimension |
| film_typeopt | COMBO | Color neg | Rebate polarity for 135/120/4x5 (Polaroid/Slide use their own surface color) |
| composeopt | COMBO | fill | fill = cover-crop into the aperture (default). fit = letterbox with rebate-color bars |
| stock_nameopt | STRING | AKURATE 400 | Edge-print / notch-code / mount-color stock name (also seeds the 4x5 notch pattern and slide mount color) |
| frame_numberopt | INT | 70–999 | First frame's edge-print number (135/120). 135 also prints the classic dual 'nA' offset |
| increment_per_frameopt | BOOLEAN | true | Batch of N -> frame_number, frame_number+1, ... +N-1 (contact-sheet workflows) |
| strip_contextopt | FLOAT | 2.00–6 | 135 full frame only: mm of neighboring strip hinted on each side |
| border_widthopt | FLOAT | 1.20–10 | 135 filed carrier only: black border thickness, mm-equivalent (ratio of 36mm) |
| roughnessopt | FLOAT | 0.500–1 | 135 filed carrier only: seeded perimeter jaggedness, 0 = straight, 1 = ~1mm-equivalent |
| paper_marginopt | FLOAT | 6.00–20 | 135 filed carrier only: white paper margin, % of the image's long edge |
| edge_print_intensityopt | FLOAT | 0.700–1 | 135/120 edge-print lettering opacity. 0 hides the lettering entirely |
| dx_barcodeopt | BOOLEAN | false | 135 full frame only: stylized DX-style bars (plausible, non-decodable) |
| date_textopt | STRING | Slide mount only: stamped date text in red-ish ink (e.g. 'MAY 74'). Empty hides it | |
| seedopt | INT | 420–4294967295 | Seeds the filed-carrier perimeter noise and the DX barcode pattern |
| backgroundopt | COMBO | black | Scanner-surround color in the small margin outside the film/print edge |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |
| image_area | MASK | — |