QR Code Image Generator
Turn an ordinary QR code into artwork. Instead of a plain black-and-white square, this blends your code directly into an image — the pattern becomes part of the composition, hidden in the textures, shadows, and shapes of the scene rather than stamped on top of it. The result still scans reliably with any phone camera, but it looks like something you'd actually want to put on a poster, album cover, business card, or product label. Just supply your link and a prompt or reference image describing the look you want, and you'll get back a piece that works as both a picture and a working code.
About
This workflow turns a plain QR code into a stylized image where the code pattern is blended into textures, shadows, and shapes rather than overlaid on top. You provide a link (or any QR payload) and either a text prompt or a reference image to describe the look you want. The system produces an artwork that still scans reliably with a phone camera while looking polished enough for posters, album covers, business cards, or product labels.
Technically, the heavy lifting happens in a single custom node (UUID: 323b0c6a-e2f0-42c3-93b4-36b7878136fd). This node encodes your URL into a QR matrix, then synthesizes or stylizes an image so local contrast and edges align with the QR modules, preserving a readable pattern inside the composition. You can balance aesthetics and readability by adjusting style strength and QR visibility. The final image is written to disk by the SaveImage node as a PNG in ComfyUI's output folder.
What you provide
- Reading the workflow
Runs in ComfyUI. This workflow can't run on this page. Open it in Comfy Cloud with everything loaded, or download it for your own ComfyUI.
Try in CloudInside the workflow
A read-only preview of the node graph. Open it in Comfy Cloud or download it to edit the nodes.
Loading the graph
Open full-size workflow preview- Author
- Purz
Requires custom nodes
- Reading the workflow
Use this workflow from code
Generated from the workflow graph and inputs when possible; stored examples are shown otherwise. Review credentials and endpoints before running code, which may incur charges.
What you need
- Runs on
- Comfy Cloud
- Key
- COMFY_API_KEY
Needs a paid Cloud plan and credits.
# Python 3.10+: pip install comfy-sdk==0.4.0
import os
from comfy_sdk import Comfy
api_key = os.environ.get("COMFY_API_KEY", "").strip()
if not api_key: raise RuntimeError("Set COMFY_API_KEY")
os.environ.setdefault("COMFY_BASE_URL", "https://cloud.comfy.org")
client = Comfy(api_key=api_key)
workflow = client.workflows.from_json({
"71": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"90:74",
0
]
},
"_meta": {
"title": "Preview Render"
}
},
"87": {
"class_type": "SaveImage",
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"90:84",
0
]
},
"_meta": {
"title": "Final Render"
}
},
"90:10": {
"class_type": "KSamplerAdvanced",
"inputs": {
"add_noise": "enable",
"cfg": 8,
"end_at_step": 1000,
"latent_image": [
"90:5",
0
],
"model": [
"90:4",
0
],
"negative": [
"90:55",
1
],
"noise_seed": 734583316628915,
"positive": [
"90:55",
0
],
"return_with_leftover_noise": "disable",
"sampler_name": "euler",
"scheduler": "normal",
"start_at_step": 0,
"steps": 25
},
"_meta": {
"title": "KSampler (Advanced) - BASE"
}
},
"90:17": {
"class_type": "VAEDecode",
"inputs": {
"samples": [
"90:10",
0
],
"vae": [
"90:4",
2
]
},
"_meta": {
"title": "VAE Decode"
}
},
"90:4": {
"class_type": "CheckpointLoaderSimple",
"inputs": {
"ckpt_name": "Juggernaut-XL_v9_RunDiffusionPhoto_v2.safetensors"
},
"_meta": {
"title": "Load Checkpoint - BASE"
}
},
"90:5": {
"class_type": "EmptyLatentImage",
"inputs": {
"batch_size": 1,
"height": [
"90:76",
0
],
"width": [
"90:76",
0
]
},
"_meta": {
"title": "Empty Latent Image"
}
},
"90:54": {
"class_type": "comfy-qr-by-module-size",
"inputs": {
"back_hexcolor": "#FFFFFF",
"border": 4,
"error_correction": "High",
"fill_hexcolor": "#000000",
"max_image_size": 768,
"module_drawer": "Rounded",
"module_size": 16,
"protocol": "None",
"text": "comfy.org"
},
"_meta": {
"title": "QR Code"
}
},
"90:55": {
"class_type": "ControlNetApplyAdvanced",
"inputs": {
"control_net": [
"90:56",
0
],
"end_percent": 1,
"image": [
"90:73",
0
],
"negative": [
"90:7",
0
],
"positive": [
"90:6",
0
],
"start_percent": 0,
"strength": 1,
"vae": [
"90:4",
2
]
},
"_meta": {
"title": "Apply ControlNet"
}
},
"90:56": {
"class_type": "ControlNetLoader",
"inputs": {
"control_net_name": "qrCodeMonsterSDXL_v10.safetensors"
},
"_meta": {
"title": "Load ControlNet Model"
}
},
"90:58": {
"class_type": "Convert Color Space",
"inputs": {
"image": [
"90:17",
0
],
"in_space": "RGB",
"out_space": "HSV"
},
"_meta": {
"title": "Convert Color Space"
}
},
"90:59": {
"class_type": "Combine Masks",
"inputs": {
"clamp_result": "yes",
"image1": [
"90:58",
0
],
"image2": [
"90:69",
0
],
"op": "add",
"round_result": "no"
},
"_meta": {
"title": "Combine Masks"
}
},
"90:6": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"90:4",
1
],
"text": "sushi"
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"90:60": {
"class_type": "Combine Masks",
"inputs": {
"clamp_result": "no",
"image1": [
"90:63",
0
],
"image2": [
"90:61",
0
],
"op": "add",
"round_result": "no"
},
"_meta": {
"title": "Combine Masks"
}
},
"90:61": {
"class_type": "Constant Mask",
"inputs": {
"copy_image_size": [
"90:63",
0
],
"explicit_height": 0,
"explicit_width": 0,
"value": -1
},
"_meta": {
"title": "Constant Mask"
}
},
"90:63": {
"class_type": "Combine Masks",
"inputs": {
"clamp_result": "no",
"image1": [
"90:73",
0
],
"image2": [
"90:64",
0
],
"op": "multiply",
"round_result": "no"
},
"_meta": {
"title": "Combine Masks"
}
},
"90:64": {
"class_type": "Constant Mask",
"inputs": {
"copy_image_size": [
"90:73",
0
],
"explicit_height": 0,
"explicit_width": 0,
"value": 2
},
"_meta": {
"title": "Constant Mask"
}
},
"90:65": {
"class_type": "Combine Masks",
"inputs": {
"clamp_result": "no",
"image1": [
"90:60",
0
],
"image2": [
"90:66",
0
],
"op": "multiply",
"round_result": "no"
},
"_meta": {
"title": "Combine Masks"
}
},
"90:66": {
"class_type": "Constant Mask",
"inputs": {
"copy_image_size": [
"90:60",
0
],
"explicit_height": 0,
"explicit_width": 0,
"value": 0.2
},
"_meta": {
"title": "Constant Mask"
}
},
"90:69": {
"class_type": "Combine Masks",
"inputs": {
"clamp_result": "no",
"image1": [
"90:65",
0
],
"image2": [
"90:77",
0
],
"op": "multiply",
"round_result": "no"
},
"_meta": {
"title": "Combine Masks"
}
},
"90:7": {
"class_type": "CLIPTextEncode",
"inputs": {
"clip": [
"90:4",
1
],
"text": "text, watermark, nudity, nsfw"
},
"_meta": {
"title": "CLIP Text Encode (Prompt)"
}
},
"90:73": {
"class_type": "ResizeImageMaskNode",
"inputs": {
"input": [
"90:79",
0
],
"resize_type": "scale dimensions",
"resize_type.crop": "center",
"resize_type.height": [
"90:76",
0
],
"resize_type.width": [
"90:76",
0
],
"scale_method": "area"
},
"_meta": {
"title": "Resize Image/Mask"
}
},
"90:74": {
"class_type": "Convert Color Space",
"inputs": {
"image": [
"90:59",
0
],
"in_space": "HSV",
"out_space": "RGB"
},
"_meta": {
"title": "Convert Color Space"
}
},
"90:76": {
"class_type": "PrimitiveInt",
"inputs": {
"value": 1024
},
"_meta": {
"title": "Int"
}
},
"90:77": {
"class_type": "Mix Color By Mask",
"inputs": {
"b": 255,
"g": 0,
"image": [
"90:78",
0
],
"mask": [
"90:78",
0
],
"r": 0
},
"_meta": {
"title": "Mix Color By Mask"
}
},
"90:78": {
"class_type": "Constant Mask",
"inputs": {
"copy_image_size": [
"90:63",
0
],
"explicit_height": 0,
"explicit_width": 0,
"value": 1
},
"_meta": {
"title": "Constant Mask"
}
},
"90:79": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"90:54",
0
]
},
"_meta": {
"title": "Preview Image"
}
},
"90:82": {
"class_type": "UltimateSDUpscale",
"inputs": {
"cfg": 8,
"denoise": 0.21,
"force_uniform_tiles": True,
"image": [
"90:74",
0
],
"mask_blur": 8,
"mode_type": "Linear",
"model": [
"90:4",
0
],
"negative": [
"90:85",
1
],
"positive": [
"90:85",
0
],
"sampler_name": "euler",
"scheduler": "simple",
"seam_fix_denoise": 1,
"seam_fix_mask_blur": 8,
"seam_fix_mode": "None",
"seam_fix_padding": 16,
"seam_fix_width": 64,
"seed": 120,
"steps": 25,
"tile_height": 1024,
"tile_padding": 32,
"tile_width": 1024,
"tiled_decode": False,
"upscale_by": 2,
"upscale_model": [
"90:88",
0
],
"vae": [
"90:4",
2
]
},
"_meta": {
"title": "Ultimate SD Upscale"
}
},
"90:84": {
"class_type": "ComfySwitchNode",
"inputs": {
"on_false": [
"90:74",
0
],
"on_true": [
"90:82",
0
],
"switch": True
},
"_meta": {
"title": "If/Else Switch"
}
},
"90:85": {
"class_type": "ControlNetApplyAdvanced",
"inputs": {
"control_net": [
"90:86",
0
],
"end_percent": 1,
"image": [
"90:74",
0
],
"negative": [
"90:7",
0
],
"positive": [
"90:6",
0
],
"start_percent": 0,
"strength": 1,
"vae": [
"90:4",
2
]
},
"_meta": {
"title": "Apply ControlNet"
}
},
"90:86": {
"class_type": "ControlNetLoader",
"inputs": {
"control_net_name": "ttplanetSDXLControlnet_v20Fp16.safetensors"
},
"_meta": {
"title": "Load ControlNet Model"
}
},
"90:88": {
"class_type": "UpscaleModelLoader",
"inputs": {
"model_name": "RealESRGAN_x4plus.pth"
},
"_meta": {
"title": "Load Upscale Model"
}
},
"90:89": {
"class_type": "PreviewImage",
"inputs": {
"images": [
"90:17",
0
]
},
"_meta": {
"title": "Preview Image"
}
}
})
# run() also passes api_key to the partner nodes in this workflow.
job = client.run(workflow, api_key=api_key)Questions & answers
Increase the QR visibility setting, reduce the overall style strength near the code, keep a clear quiet zone (blank margin) around the QR area, and avoid extreme blur or heavy texture over modules. Also test under normal indoor lighting and ensure the final crop doesn’t cut into the code edges.
Yes. Provide a reference image to the custom QR node. The node will align textures and edges to the QR matrix while borrowing colors and structure from your reference. If the code becomes hard to scan, reduce style strength or simplify the reference.
Start with a square canvas to keep the QR proportions consistent. Higher resolution improves detail, but ensure the QR modules remain crisp with good contrast. For print, generate at the final print size or plan to upscale with care and re-test scanning afterward.
The SaveImage node writes the outputs as PNG files in your ComfyUI/output folder. Each run will create a new file; use the seed or naming options to keep versions organized.