Add Qwen Image Edit Single MXD node

Introduces the QwenImageEditSingleMXD node for single-image editing with prompt and optional image input, supporting reference latents and VAE encoding. Updates node mappings and display names accordingly. Bumps project version to 1.5.1.
This commit is contained in:
Maxed-Out-99
2026-01-15 14:02:04 -08:00
parent 3641c2ab57
commit e8ef3e338a
2 changed files with 63 additions and 1 deletions
+62
View File
@@ -3,6 +3,7 @@ import torch, math, comfy, os, folder_paths, node_helpers, comfy.model_managemen
from comfy.comfy_types import IO, ComfyNodeABC, InputTypeDict
import numpy as np
from PIL import Image, ImageOps, ImageSequence
from comfy_api.latest import io
########################################################################################################################
# Flux Empty Latent Image (SD3-compatible)
@@ -425,6 +426,65 @@ class PromptWithGuidance(ComfyNodeABC):
conditioning = clip.encode_from_tokens_scheduled(tokens)
conditioning = node_helpers.conditioning_set_values(conditioning, {"guidance": guidance})
return (conditioning,)
########################################################################################################################
# Qwen Image Edit Single MXD
class QwenImageEditSingleMXD(io.ComfyNode):
@classmethod
def define_schema(cls):
return io.Schema(
node_id="QwenImageEditSingleMXD",
display_name="Qwen Image Edit Prompt Single MXD",
category="MXD/conditioning",
description="Encode a prompt and optional image for Qwen single-image editing.",
inputs=[
io.Clip.Input("clip"),
io.String.Input("prompt", multiline=True, dynamic_prompts=True),
io.Vae.Input("vae", optional=True),
io.Image.Input("image", optional=True),
],
outputs=[
io.Conditioning.Output(),
],
)
@classmethod
def execute(cls, clip, prompt, vae=None, image=None) -> io.NodeOutput:
ref_latents = []
images_vl = []
llama_template = "<|im_start|>system\nDescribe the key features of the input image (color, shape, size, texture, objects, background), then explain how the user's text instruction should alter or modify the image. Generate a new image that meets the user's requirements while maintaining consistency with the original input where appropriate.<|im_end|>\n<|im_start|>user\n{}<|im_end|>\n<|im_start|>assistant\n"
image_prompt = ""
if image is not None:
samples = image.movedim(-1, 1)
total = int(384 * 384)
scale_by = math.sqrt(total / (samples.shape[3] * samples.shape[2]))
width = round(samples.shape[3] * scale_by)
height = round(samples.shape[2] * scale_by)
s = comfy.utils.common_upscale(samples, width, height, "area", "disabled")
images_vl.append(s.movedim(1, -1))
if vae is not None:
total = int(1024 * 1024)
scale_by = math.sqrt(total / (samples.shape[3] * samples.shape[2]))
width = round(samples.shape[3] * scale_by / 8.0) * 8
height = round(samples.shape[2] * scale_by / 8.0) * 8
s = comfy.utils.common_upscale(samples, width, height, "area", "disabled")
ref_latents.append(vae.encode(s.movedim(1, -1)[:, :, :, :3]))
image_prompt += "Picture 1: <|vision_start|><|image_pad|><|vision_end|>"
tokens = clip.tokenize(image_prompt + prompt, images=images_vl, llama_template=llama_template)
conditioning = clip.encode_from_tokens_scheduled(tokens)
if len(ref_latents) > 0:
conditioning = node_helpers.conditioning_set_values(
conditioning,
{"reference_latents": ref_latents},
append=True,
)
return io.NodeOutput(conditioning)
########################################################################################################################
class FluxResolutionMatcher:
@@ -1080,6 +1140,7 @@ NODE_CLASS_MAPPINGS = {
"Image Scale To Total Pixels (SDXL Safe)": SDXLImageScaleToTotalPixelsSafe,
"Flux Image Scale To Total Pixels (Flux Safe)": FluxImageScaleToTotalPixelsSafe,
"Prompt With Guidance (Flux)": PromptWithGuidance,
"QwenImageEditSingleMXD": QwenImageEditSingleMXD,
"FluxResolutionMatcher": FluxResolutionMatcher,
"SDXLResolutionMatcher": SDXLResolutionMatcher,
"LatentHalfMasks": LatentHalfMasks,
@@ -1099,6 +1160,7 @@ NODE_DISPLAY_NAME_MAPPINGS = {
"Image Scale To Total Pixels (SDXL Safe)": "Scale SDXL Image MXD",
"Flux Image Scale To Total Pixels (Flux Safe)": "Scale Flux Image MXD",
"Prompt With Guidance (Flux)": "Prompt with Flux Guidance MXD",
"QwenImageEditSingleMXD": "Qwen Image Edit Prompt Single MXD",
"FluxResolutionMatcher": "Flux Resolution Matcher MXD",
"SDXLResolutionMatcher": "SDXL Resolution Matcher MXD",
"LatentHalfMasks": "Latent to L/R Masks MXD",
+1 -1
View File
@@ -1,7 +1,7 @@
[project]
name = "maxedout"
description = "Custom ComfyUI nodes used in Maxed Out workflows (SDXL, Flux, Wan 2.2, etc.)"
version = "1.5.0"
version = "1.5.1"
license = {file = "LICENSE"}
# classifiers = [
# # For OS-independent nodes (works on all operating systems)