arkennemasis fal · Flux LoRA Canny · $0.035/MP
Keep the edges, change everything they contain
- image
- images
- image_paths
- timings
- seed
- prompt
- has_nsfw_concepts
- info
Canny conditioning is the blunt instrument of the ControlNet world and it's still the best one for a specific job: holding the shape of a reference while you replace the substance. A doorframe stays a doorframe, a wheel stays round, the roofline stays where it was - and the render becomes whatever your prompt says. This node does it on Flux Dev with LoRA support, hosted, at $0.035 per megapixel.
How canny conditioning works
Canny detects hard edges with configurable thresholds and produces thin, high-contrast edge maps - which is why the classic use cases are architecture, mechanical objects and any scene with clear contours. The geometry is extracted from the reference, generation follows the edges, and the prompt decides the materials, the lighting and the style.
The thing people used to ControlNet from the SD days should brace for here: this node has no control weight, no start/end step, no preprocessor choice. There's an image socket, and the endpoint handles the conditioning at its own weighting. A lot of the traditional advice - release the condition after composition forms, weight 0.8–1.2 for strict adherence - is about dials that don't exist on this node. What you control is the input picture, the prompt, and the seed.
Inputs
image- the edge-condition input. Cleaner source, cleaner guidance.prompt- what the shapes should become.loras- a JSON string of LoRA entries with weights and scale, merged together. Empty leaves it out. They resolve on fal's side.image_size(defaults tosquare_hdhere) plusimage_size_width/image_size_heightforcustom(16–14142, step 16). Set it to match your input's framing unless you want the layout re-cropped around the edges you supplied.guidance_scale3.5 (0–35),num_inference_steps28 (1–50),seed,num_images1–4,enable_safety_checker,output_format,acceleration.
The four pack-wide widgets sit at the bottom: max_cost_usd (default 20), reuse_identical_run (on - repeat runs return the paid files), extra_json, max_concurrent.
Outputs
images → preview or save. image_paths points into output/fal/fal-ai_flux-lora-canny/. seed, prompt and info come back for reproducibility and debugging; has_nsfw_concepts tells you whether the safety checker flagged the result, and timings is there if you care how long the wait was.
Install
cd ComfyUI/custom_nodes
git clone https://github.com/Hishamahmer/comfyui-arkennemasis
Manager users: search comfyui-arkennemasis or use Install via Git URL. Restart ComfyUI. No local model downloads, obviously - that's the whole point of the fal nodes.
# .env in the folder with run_nvidia_gpu.bat
FAL_KEY=your-key-from-fal.ai/dashboard/keys
No key box on the node, by design.
Where it goes sideways
Edges ignored. Canny needs contrast. A soft, low-light, hazy reference produces a sparse edge map, and the model is then largely inventing from your prompt. Brighten and sharpen upstream, or pick an input with actual contours in it.
Edges obeyed too literally. Small details in the map can show up as artefacts - the classic "the model faithfully reproduced the flyer stapled to the wall as a weird blob" problem. Simplifying the input (blur, downscale and upscale) helps.
Batching. Treat these sockets as one picture each. If a loader hands you a batch, split it first rather than assuming the endpoint knows what to do with a stack.
Cost per attempt. Iterating on a prompt costs a real 3.5 cents per megapixel each time, and num_images 4 is four times that. Use acceleration while you're searching for the prompt, then turn it back to none for the keepers.
Inputs (17)
| Name | Type | Default | Description |
|---|---|---|---|
| prompt | STRING | The prompt to generate an image from. | |
| image_size | COMBO | square_hd | The size of the generated image. 'custom' uses the width and height below. |
| image_size_width | INT | 102416–14142 | Width in pixels when image_size is 'custom'. |
| image_size_height | INT | 102416–14142 | Height in pixels when image_size is 'custom'. |
| num_inference_steps | INT | 281–50 | The number of inference steps to perform. |
| seed | INT | -1-1–2147483647 | The same seed and the same prompt given to the same version of the model will output the same image every time. -1 leaves it to the model. |
| loras | STRING | The LoRAs to use for the image generation. You can use any number of LoRAs and they will be merged together to generate the final image. JSON. Empty leaves it out. | |
| guidance_scale | FLOAT | 3.500–35 | The CFG (Classifier Free Guidance) scale is a measure of how close you want the model to stick to your prompt when looking for a related image to show you. |
| num_images | INT | 11–4 | The number of images to generate. This is always set to 1 for streaming output. |
| enable_safety_checker | BOOLEAN | true | If set to true, the safety checker will be enabled. Disabling it requires account authorization; unauthorized requests are always checked, and images flagged as unsafe are returned as black images. |
| output_format | COMBO | jpeg | The format of the generated image. |
| acceleration | COMBO | none | Acceleration level for image generation. 'regular' balances speed and quality. |
| image | IMAGE | URL of image to use for canny input | |
| max_cost_usdopt | FLOAT | 20.00–100000 | Safety cap. If the estimated cost of this run is above this many US dollars the node stops BEFORE sending anything to fal. 0 = no cap. |
| reuse_identical_runopt | BOOLEAN | true | If these exact inputs (the settings AND the same pictures/clips/audio) were already paid for and the files are still in output/fal, return them instead of paying again - also after a ComfyUI restart. Turn off for a fresh take with the same settings. |
| extra_jsonopt | STRING | Advanced: a JSON object merged into the request last, for any fal field this node has no box for. Example: {"seed": 7}. Leave empty normally. | |
| max_concurrentopt | INT | 11–32 | How many paid fal calls may run at the same time in one run, across every fal node. 1 (default) = one after another. This node starts its paid part only while fewer than this many fal calls are running. Once any fal node fails, the ones still waiting are not started, so nothing more is billed. |
Outputs (7)
| Name | Type | Description |
|---|---|---|
| images | IMAGE | — |
| image_paths | STRING | — |
| timings | STRING | — |
| seed | INT | — |
| prompt | STRING | — |
| has_nsfw_concepts | STRING | — |
| info | STRING | JSON: request id, cost estimate, saved files and fal's full answer. |