ComfyUI Node

Halftone

Real halftone dots, not a filter

By jeremieLouvaert·Created 5 months ago·Updated 2 days ago· 101
Halftone
  • image
  • image
color_modemono (black)
methodAM (clustered dot)
dot_shaperound
lines100
angle45
black_generation1.00
supersample2
strength1.00

The newsprint and comic look is actually a physical process: continuous-tone images get reproduced as a grid of ink dots whose size grows with tone. Dark spots have big dots, bright spots have small ones. That's halftone screening, and it's surprisingly hard to do convincingly - most "halftone" filters just tile a dot pattern over the image and call it a day. Halftone in the Darkroom pack builds the dots from the actual image tones, with real screen angles and dot shapes, and it's GPU-accelerated to boot.

How it works

The node converts image tones to dot coverage and then renders a dot grid where each dot's size tracks the local tone. But the real details are where it shines:

  • Two methods. AM (amplitude modulation, the default) renders clustered dots whose size carries the tone - the classic newsprint look. FM (frequency modulation) uses dispersed Bayer dithering - the stochastic-style "ink jet" pattern where dot spacing varies instead of size. The FM mode ignores dot_shape, angle, and supersample, as the tooltip warns.
  • Four dot shapes - round (classic), line (engraving/linocut screen), square (retro), and ellipse (chain dots). The shapes are tone-linearized, so changing the shape changes dot geometry, not overall brightness.
  • Real screen angles. Mono defaults to 45° - the classic newspaper angle. In color (CMYK) mode it uses the standard rosette at 15/75/0/45°, the actual angles print shops use.
  • lines (20–400) sets screen frequency - lines across the long edge - and it's resolution-independent, so the screen reads the same at any image size.
  • black_generation - CMYK only, 0–1. 1 = full GCR (black plate derived from min CMY), 0 = CMY only. It's the same GCR (Gray Component Replacement) control print workflows care about.
  • supersample (1–4) anti-aliases dot edges. Higher is smoother and slower.
  • strength - blend back to the original. Less than 1 gives a subtle screen overlay, which is a genuinely nice stylize trick.

Mono or color?

color_mode toggles between mono (black) - newsprint black on white, the classic look - and color (CMYK), a naive CMYK separation that gives you the four-color rosette. The tooltip and README are both explicit that this is a stylize effect, not a calibrated proof - if you actually need to know what an image looks like on press, use the pack's CMYK Soft-Proof node instead. But for a comic book cover or a zine aesthetic, it's spot on.

Where it fits

It's under AKURATE/Darkroom/Print, alongside the CMYK workflow nodes. It's a spatial effect (each dot depends on its neighbors), so the README excludes it from LUT bake chains - apply it after extraction. Output is a single image.

One practical note: halftone dots live and die by resolution. If you halftone a small image, the dots are chunky and the print look gets lost; upscale first, then halftone, then downscale if needed. The resolution-independent lines control helps, but dot edges still need pixels to look like dots.

Installing it

Part of the full ComfyUI-Darkroom pack:

cd ComfyUI/custom_nodes
git clone https://github.com/jeremieLouvaert/ComfyUI-Darkroom.git
pip install -r ComfyUI-Darkroom/requirements.txt

Or search "Darkroom" in ComfyUI Manager. Needs scipy, opensimplex, rawpy, exifread, Pillow. Restart and it's under AKURATE/Darkroom/Print. Unlike most of the pack, this one runs its dot rendering on the GPU (torch) - still no model files, no API, nothing to license.

CategoryAKURATE/Darkroom/Print

Inputs (9)

NameTypeDefaultDescription
imageIMAGE
color_modeoptCOMBOmono (black)mono = newsprint black-on-white; color = naive CMYK rosette
methodoptCOMBOAM (clustered dot)AM = clustered dots (size-modulated). FM = dispersed Bayer dither (stochastic-style). FM ignores dot_shape, angle, and supersample.
dot_shapeoptCOMBOroundAM dot shape. round = classic; line = engraving/linocut screen; square = retro; ellipse = chain dot. AM only.
linesoptINT10020–400Halftone lines across the long edge (resolution-independent screen frequency)
angleoptFLOAT450–90Mono screen angle in degrees (classic newspaper = 45°). Ignored in CMYK (fixed rosette).
black_generationoptFLOAT1.000–1CMYK only: 1 = full GCR (K plate from min CMY), 0 = CMY only
supersampleoptINT21–4Dot-edge anti-aliasing. Higher = smoother edges + slower.
strengthoptFLOAT1.000–1Blend original (0) ↔ halftone (1). <1 = subtle screen overlay.

Outputs (1)

NameTypeDescription
imageIMAGE