Uniform cell size (max ref dims) still force-shrank outliers to match
unrelated refs even without cropping. Justified rows (Flickr-style:
row height = target width / sum of aspect ratios) size each row from
its own refs' aspect ratios, so a wide or tall outlier gets its own
proportioned row instead.
_build_sheet used cover-fit (crop overflow) against the largest ref's
cell size. Switched to contain-fit (pad instead of crop) so no
reference image gets cut off.
Extracts shared image helpers from Reference Concat into _image_ops.py
and adds a new Reference Grid node with columns, fit_mode (cover/
contain/stretch), cell_size_source, fill_direction, and last_row_align
controls. Reference Concat's legacy grid fallback is unchanged.
Upscaling smaller references to match the largest one meant a single
oversized outlier (e.g. 8000x9000) blew up the whole contact sheet or
strip. max_ref_side downscales (never upscales) any reference over the
limit before sizing math runs, using the existing interpolation filter.
Reference Concat's contact-sheet mode picked cell size from the median
of the batch, so a single low-res reference capped every other tile's
resolution once upstream batching forced a common size.
Add Image List: auto-expanding IMAGE sockets (same pattern as Dynamic
LoRA Stack) that output a native ComfyUI list instead of a stacked
tensor, so mixed-resolution references never get resized before
Reference Concat sees them.
Reference Concat now declares INPUT_IS_LIST, accepts either an Image
List or a legacy stacked batch, sizes its contact sheet from the
largest reference (upscaling smaller ones to match instead of the
reverse), and adds an interpolation widget (nearest/bilinear/bicubic/
lanczos) used for all internal resizing.
main_image is now optional. Without it, reference_images are laid out
as an auto-sized grid (cover-fit cells, no cropping distortion) instead
of a strip, for building plain reference sheets.
Uniform-scale-to-fill math made final thickness = target_length /
sum(aspect_ratios), independent of ref_scale. Now ref_scale sets
thickness directly; target_length is a cap (scale down only on
overflow), padding with fill color when the strip is under the cap.
Concatenates a batch of reference images into an identity strip against
a main image, sized to exactly fill the main image's longest side with
no resolution cap, main image never shrunk. Offset controls overlap vs
gap; outputs a mask marking the strip region.