OpenCV putText_0
Watermarks, labels, and annotations with OpenCV putText_0
- img
- nparray
putText_0 is the node that draws text onto an image - watermark "my handle @example", label a detected region, timestamp a video frame. It's cv2.putText from the opencv-comfyui pack, and it's one of the handful of nodes in this auto-generated collection you'll genuinely reach for, because adding text to a finished image is a real, recurring job and ComfyUI core doesn't hand you a text-overlay node on a plate.
The function is the classic OpenCV text renderer: bitmap fonts built into OpenCV, no font files to download, no GPU, millisecond-fast. You hand it the image, the string, where to put it, and how to style it, and it returns the image with the text baked in. The text is drawn directly into the array, so it's part of the pixels after this node - wire the output into Nparrays2Image and then into a Save node and you've got a watermarked export.
The inputs you'll actually touch
img(NPARRAY) - the image to draw on. Works with BGR or grayscale arrays.text(STRING) - what to write.org(STRING) - the bottom-left corner of the text, as a Python literal:(x, y). Remember, it's the bottom-left, not top-left - the text extends up and right from this point. This is where new users get surprise text sitting off-screen.fontFace(INT) - the font enum. The ones you'll use:0= FONT_HERSHEY_SIMPLEX (the default-ish workhorse),1= PLAIN (thin),5= COMPLEX_SMALL (compact).fontScale(FLOAT) - text size. This is relative, not pixels - a1.0on a 512px image is small; on a 4096px image it's invisible. Scale it up for big images.color(STRING) - as a Python literal:(b, g, r). It's BGR order, matching OpenCV convention, and values go 0..255 - so pure red is(0, 0, 255), not(255, 0, 0), and not1.0. This is the trap that gets everyone at least once.thickness(INT),lineType(INT),bottomLeftOrigin(BOOLEAN).thicknessis line weight in pixels;lineTypeof16(LINE_AA) gives anti-aliased text;bottomLeftOriginflips the y-axis interpretation if you're working in image-coordinate conventions.
The output is a single nparray.
Where the "expect dragons" warning bites
The pack's author, Gerold Meisinger, told r/comfyui when he released it that these nodes are "ugly and complex to use. Expect dragons!" For putText_0, the dragons are: the org and color literal syntax (any typo → "invalid syntax (<unknown>, line 0)" with no hint which field), the BGR color order, and the relative fontScale. Once you've internalized (x, y) and (b, g, r), it's actually one of the friendlier nodes here.
Install
Same as every node in the pack: ComfyUI Manager → search "opencv-comfyui", or
cd ComfyUI/custom_nodes
git clone https://github.com/geroldmeisinger/opencv-comfyui
restart, then pip install opencv-contrib-python. Chain IMAGE → Image2Nparray → putText_0 → Nparrays2Image → Save Image, batch size 1 only (ImageFromBatch length 1 fixes the batch error). There's also a putText_1 twin, identical, generated from the second overload.
The verdict
If you want a watermark with transparency, kerning, or any real typography, this isn't it - OpenCV's bitmap fonts are basic and always opaque. But for stamping a label, a prompt, or a handle onto an image as part of an automated pipeline, putText_0 is deterministic, dependency-free, and gets the job done. It's one of the few nodes in this pack where "thin auto-generated wrapper" is actually a feature.
Inputs (9)
| Name | Type | Default | Description |
|---|---|---|---|
| img | NPARRAY | — | |
| text | STRING | — | |
| org | STRING | — | |
| fontFace | INT | — | |
| fontScale | FLOAT | — | |
| color | STRING | — | |
| thickness | INT | — | |
| lineType | INT | — | |
| bottomLeftOrigin | BOOLEAN | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| nparray | NPARRAY | — |