Nodes/Qwen Image References Manager/Qwen Image References Manager
ComfyUI Node

Qwen Image References Manager

Ten Reference Images, One Grid, and No Prompt Magic

By Hearmeman24·Created 24 days ago·Updated 24 days ago· 2
Qwen Image References Manager
    • image_1
    • image_2
    • image_3
    • image_4
    • image_5
    • image_6
    • image_7
    • image_8
    • image_9
    • image_10
    ◄references_json►
    ◄max_reference_edge2048►

    If your Qwen graph wants several reference images at once, the boring version of that problem is nine LoadImage nodes, nine upload clicks you can't see together, and an ImageCrop for every trim. The Qwen Image References Manager replaces that with a 5×2 tile grid inside one node body and ten IMAGE sockets out the bottom. That's the whole pitch - it's a front-end convenience node.

    What it is, and what it deliberately isn't

    The README targets Qwen Image 2.1. Be a little sceptical of the name: community coverage of the family stops at Qwen-Image-2.0 - the February 2026 7B unified generation-and-edit model that shipped API-only, no open weights - so "2.1" is the author's own lineage reference. It doesn't change what you do here. The node hands you images; whatever consumes references in your Qwen graph takes it from there.

    What it doesn't do matters more. No prompt writing, no text encoder, no API key, no video or audio - image references only, and the README says so flatly.

    How it works

    The tiles are JavaScript drawing into a canvas in the node body. Your real state - file, crop, rotation, mirror - rides in a hidden STRING widget called references_json, which the frontend keeps in sync and swaps out of view. Widget hiding is fussy on the V3 frontend, so the pack's JS locks hidden and type down and refuses to throw when a frontend makes those getter-only. You never see the JSON, and you shouldn't hand-edit it.

    On queue, Python validates before it touches a pixel: at most ten references, each kind: image, each file a relative path that resolves inside ComfyUI/input/. Absolute paths, .. and backslashes get rejected, so a shared workflow can't read your home directory through this node. Crop must be a rectangle in 0–1 fractions; rotation must be 0, 90, 180 or 270.

    Then each image loads in a fixed order: EXIF correction, then rotation (clockwise quarter turns) and mirror, then crop, then the long-edge cap. Crop fractions refer to the image as the editor shows it, which is exactly why that order can't be shuffled. The cap uses PIL's thumbnail, so it only ever shrinks - anything already under your limit passes through untouched, and because it runs last it measures what actually leaves the node.

    The inputs and outputs that matter

    max_reference_edge is the one you'll set. Default 2048, range 0–8192 in steps of 64, and 0 disables downscaling. The default isn't paranoia: reference sizing in ComfyUI keys off the short edge, so a wide image gets scaled until its short side fits and leaves you a very long edge you never budgeted for. Reference tokens ride every sampling step, so an oversized reference quietly becomes the most expensive thing in your graph - the pack's own notes name a 5000×2550 sheet as the case in point.

    references_json is written by the image manager. Leave it alone.

    Ten outputs, image_1 through image_10, all IMAGE. Wire them into whatever reference inputs your Qwen node exposes - and wire only the tiles you filled. Empty sockets return None, and None arriving at a node that expects a tensor is an error, not a skip.

    Install

    No models, no dependency wrangling. It's Python on PIL/numpy/torch, all of which ComfyUI already ships.

    cd ComfyUI/custom_nodes
    git clone https://github.com/Hearmeman24/ComfyUI-QwenImageRefPack.git
    

    Restart ComfyUI, or just search Qwen Image References Manager in ComfyUI Manager. The node lives under the Qwen Image category.

    Where people get burned

    The references don't travel. references_json stores filenames, and files live in ComfyUI/input/ - the same place a UI upload lands. Download someone's workflow or a shared PNG and the graph names their images, not yours. Queue it and you get reference file(s) not found in the ComfyUI input directory: followed by the names, which is at least honest. Re-add your own.

    Caching follows the file, not the pixels. IS_CHANGED hashes each filename with its mtime and byte size, plus your edits and the cap - so nudging a crop re-runs the node instead of serving you stale tensors. The flip side: swap an image in input/ in a way that preserves both size and timestamp and you'll get the old tensors. Re-upload, or force a refresh.

    The frontend is the fragile part. Hiding widgets and drawing a canvas are two of the things the Nodes 2.0 migration has broken for third-party packs. If the grid doesn't render, open the browser console before declaring the node dead - and don't "fix" it by editing hidden JSON.

    One free debugging tool: this pack was carved out of the author's video reference pack, and the log lines kept the old prefix. Grep the console for MiniMaxRefPack and you get one line per load with file=, crop=, rotation=, mirror=, cap=, src=/out= dimensions and milliseconds - the fastest way to see what resolution actually left a socket. Failures log ok=false error=<type>.

    On the author: HearmemanAI is better known for one-click RunPod Wan templates than for node packs. Not a knock here - there's genuinely nothing in this node to break.

    CategoryQwen Image

    Inputs (2)

    NameTypeDefaultDescription
    references_jsonoptSTRINGReference list written by the image manager. Do not hand-edit.
    max_reference_edgeoptINT20480–8192Downscale references whose long edge exceeds this. 0 disables the cap.

    Outputs (10)

    NameTypeDescription
    image_1IMAGE—
    image_2IMAGE—
    image_3IMAGE—
    image_4IMAGE—
    image_5IMAGE—
    image_6IMAGE—
    image_7IMAGE—
    image_8IMAGE—
    image_9IMAGE—
    image_10IMAGE—