Nodes/ComfyUI CV/cv2.getFontScaleFromHeight
ComfyUI Node

cv2.getFontScaleFromHeight

\"Make this label 40 pixels tall\" — the number putText never gave you

By bmad4ever·Created 4 months ago·Updated 15 days ago· 1
cv2.getFontScaleFromHeight
    • float
    ◄fontFaceFONT_HERSHEY_SIMPLEX►
    ◄pixelHeight0►
    ◄thickness1►

    cv2.putText takes a fontScale - a unitless multiplier on the font's own baseline geometry - which means "0.8" is not a size, it's a guess you tune by eye until the text looks about right. cv2.getFontScaleFromHeight converts a real measurement into that guess. Tell it you want glyphs 40 pixels tall and it tells you the scale to pass.

    I ran it on a 4.8 build to be sure of the numbers: FONT_HERSHEY_SIMPLEX, height 40, thickness 2 → 1.833. So a label you want 40 px tall goes into putText with fontScale = 1.833, and it comes out 40 px tall instead of "sort of 30-something".

    The inputs

    • fontFace - a dropdown of the Hershey faces, defaulting to FONT_HERSHEY_SIMPLEX. It must match the face you'll actually draw with, because each one has different baseline geometry.
    • pixelHeight - the target height, in pixels. It opens at 0, and 0 gives you a negative fontScale (I measured about -0.048), which draws invisible or mirrored text rather than erroring. That's the trap in this node: no message, just a blank label.
    • thickness - optional, defaults to 1. The height calculation accounts for stroke width, so pass the same thickness you'll hand putText. Otherwise you're a couple of pixels off, which matters when you're aligning text to something.

    One output, float - the fontScale. Wire it straight into the fontScale input of the cv2.putText wrapper, and put the same fontFace and thickness there too.

    Why you'd bother

    Any time a graph draws on its own images and the images aren't a fixed size. Bake fontScale = 1 into an annotation node and your labels are fine on a 1024px preview and unreadable on a 4K one - or comically large on a 256px thumbnail. Compute the height from the frame instead (~3% of image height) and every diagnostic overlay the pack draws - keypoint ids, box labels, pose annotations, matrix readouts - stays legible regardless of what resolution flows through.

    The second case is legibility after downscaling. A 12 px label is fine until the image gets resized for a contact sheet, at which point it's a smudge. Knowing the actual pixel height lets you decide "minimum 18 px" and enforce it.

    Install

    Manager → search ComfyUI CV, or:

    cd ComfyUI/custom_nodes
    git clone https://github.com/bmad4ever/comfyui_cv
    pip install "opencv-contrib-python-headless~=5.0.0.93"
    

    Restart. Python ≥ 3.12, recent ComfyUI on the V3 node API. Nothing to download, and this function has been in OpenCV for years.

    Where people get burned

    • Leaving pixelHeight at 0. Negative fontScale, invisible text, no error. Set a real number.
    • Mismatched faces. The scale is computed for the fontFace you selected, not for text you draw with a different one. Same for thickness.
    • Expecting it to reserve space. This returns a scale, not a bounding box; if you're laying out a text on a canvas you still need cv2.getTextSize to know the width and baseline. The pack wraps that too.
    • Treating it as a hard promise. The returned scale is about the font's cap/baseline geometry, so a string with descenders or accents on a different face lands a pixel or two off what you asked for. For overlays, that's irrelevant. For pixel-perfect typography, you're using the wrong library.
    Categoryimage/CV/low-level/cv2 G

    Inputs (3)

    NameTypeDefaultDescription
    fontFaceCOMBOFONT_HERSHEY_SIMPLEXFont to use, see cv::HersheyFonts.
    pixelHeightINT0-2147483648–2147483647Pixel height to compute the fontScale for
    thicknessoptINT1-2147483648–2147483647Thickness of lines used to render the text.See putText for details. Preset to the OpenCV default (1).

    Outputs (1)

    NameTypeDescription
    floatFLOAT—