CV Color From Hex
The colour picker that talks to cv2's BGR draw calls
- color
- tuple_string
What this is for
Two colour systems live in ComfyUI and they refuse to meet in the middle. Native nodes and the frontend speak #RRGGBB - ComfyUI's COLOR widget type is literally a colour picker. OpenCV's drawing functions want a tuple, and they want it in BGR, and the pack's draw nodes take that tuple as a string literal like '(0, 0, 255)'. So the moment you want to draw the same accent colour you used everywhere else, you're hand-converting hex to BGR in your head, which is exactly the kind of small arithmetic nobody should be doing at 1am.
This node is a type bridge. Pick a colour, get the tuple string.
How it works
color is parsed as an sRGB hex string and renders as a native colour picker widget in the UI. Then code decides the colour space: the default COLOR_RGB2BGR suits OpenCV's draw nodes directly (#00ff00 → (0, 255, 0)). Pick none (RGB) to pass the sRGB value through untouched, or any of the cvtColor codes if you need HSV/HLS/Lab in the tuple - useful when you're feeding a threshold or a comparison rather than a brush.
scale_to_range is the clever one, and the tooltip is precise about why it exists: it divides each channel by the maximum the target format's channel can hold. That's 179 for H in HSV/HLS (OpenCV's uint8 hue runs 0–179, the half-degree wrap), 255 for H in HLS_FULL, and 255 for everything else. Leave it off for raw uint8 tuples, turn it on when a downstream node wants normalised 0–1 values. Without that per-channel max you'd "normalise" a hue on the wrong denominator and wonder why everything came out green.
One input set, one output: tuple_string, e.g. '(0, 0, 255)', wired into the colour input of the draw nodes.
A note on the value it isn't
This is not a colour conversion node in the sense of transforming an image - it converts a literal. If you want an image's colours changed, that's cv2_cvtColor or the pack's own conversion nodes. This one is plumbing: the KB's framing applies exactly, in that a value node's job is to make one authoritative source for something the graph uses in several places. Set the hex here, fan tuple_string to CV Draw Polygon, CV Draw Text and whatever else, and the accent stays consistent - which is the same argument as Primitive nodes over typed-in widget values.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
# restart ComfyUI
Or search ComfyUI CV in ComfyUI Manager (publisher bmad4ever). Python ≥ 3.12, V3-node-API ComfyUI, opencv-contrib-python-headless~=5.0.0.93 from the pack's requirements. Nothing to download; no model, no extra library.
Common issues
- The colour picker shows as plain text. The widget is a frontend extension; hard-reload the page and it appears.
- Everything looks like a different colour than you picked. You are almost certainly feeding an RGB tuple where OpenCV wants BGR. Check
code- the default handles it for draw nodes, butnone (RGB)is a deliberate escape hatch, not a fix. - A tuple that should be
(0, 0, 255)comes out with fractions.scale_to_rangeis on. Both modes are legitimate; know which one the downstream node wants. - The whole pack's contrib nodes disappeared. Something installed a non-contrib OpenCV wheel over the shared
site-packages/cv2.python tools/repair_opencv_contrib.py --check, then--applyto repair.
Inputs (3)
| Name | Type | Default | Description |
|---|---|---|---|
| color | COLOR | #00ff00 | Input color in #RRGGBB hex format - renders as a native color picker in the UI. |
| code | COMBO | COLOR_RGB2BGR | cv2 cvtColor conversion code. 'none (RGB)' passes the sRGB value through unchanged. |
| scale_to_range | BOOLEAN | false | When enabled, each channel is divided by its uint8 range max (179 for H in HSV/HLS, 255 else) so the tuple lands in [0, 1]. Disabled = raw uint8 values. |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| tuple_string | STRING | Tuple literal, e.g. '(0, 0, 255)' - feed into draw nodes' colour input. |