The complete guide to AI image generation

By

Learn AI image generation from prompts to finished assets, with hosted models, creative tools, local workflows, ComfyUI, and JavaScript APIs.

~~~

You can generate an image by describing it in ChatGPT. You can also download a model, run it on your computer, and build a workflow that produces hundreds of assets with the same settings.

Between those two approaches there are design applications, image editing tools, hosted APIs, and visual workflow builders. They overlap, but they give you different kinds of control.

This guide explains how to choose between them and use them. We’ll work with a small project: an illustration for a fictional bicycle repair shop called Officina. We’ll develop the image, change it, prepare it for a website, and see how to repeat that work through code or a local model.

The product and API examples follow official documentation checked in October 2026. I haven’t benchmarked all these models or run every generation workflow below. Treat the exercises as a way to evaluate them on your own work, rather than a ranking based on my testing.

Daniel Ball’s practical guide and the discussion on Hacker News prompted this article. The distinction between generating a convincing picture and producing a usable asset deserves particular attention. A picture of a sprite sheet can still need substantial work before a game can use it.

Start with the job you need to do

An image generator can help you explore a visual idea, produce an illustration, edit a photograph, or make variations of an existing design.

Those jobs need different capabilities. For a background illustration, you might accept a wide range of compositions. For a product photograph, changing the shape of the product makes the result unusable.

Before opening a tool, write down the output you need.

For Officina, our brief is:

A wide illustration for the homepage of a bicycle repair shop. One blue city bicycle on the right, a small repair stand behind it, and a plain light background. Leave the left third empty for a heading. Use a flat editorial illustration style with dark outlines and a limited palette. The image contains no lettering. The final web asset will be 1600 × 900 pixels.

This gives us something to evaluate. We can check whether the bicycle makes sense and whether the crop leaves room for the heading.

The final dimensions describe the deliverable. A particular model might generate at a different size, so we’ll resize or crop afterward.

Keep the headline in HTML. That makes it accessible, translatable, and editable without generating another picture.

Your jobCapability to look forA useful first route
Explore an ideaText-to-image and variationsA chat app or creative image tool
Change an existing pictureImage input and instruction-based editingA model with an explicit editing workflow
Fix a small regionMasks and inpaintingAn image editor or a local workflow
Keep a product recognizableReference inputs and careful preservationA reference-based editor, checked against the original
Match a sketch or poseStructural conditioningComfyUI with a compatible control model
Produce editable iconsVector outputA vector generator or SVG drawn in code
Repeat a process in an appAPI access and predictable output handlingA direct API or hosted inference provider
Keep inference on your machineDownloadable weights and a compatible runnerDraw Things, MFLUX, or ComfyUI

A tool that excels at one row can be awkward at another. Choose an initial route from your task, then test it with your own brief.

Model, product, and provider mean different things

A model is the trained system that generates or edits the image. GPT Image, FLUX, and Qwen Image are model families.

A product supplies the interface around a model. It might give you a canvas, a chat conversation, layer editing, saved projects, or reference controls. ChatGPT and ComfyUI are products with very different interfaces.

A provider runs a model for you. A provider can offer its own models, models from other companies, or both.

This distinction explains why the same model can feel different in two applications. One application might rewrite your prompt, select quality settings, or resize the output. Another might expose the underlying settings directly.

It also explains why installing a local interface doesn’t guarantee local generation. A ComfyUI workflow can call a paid remote model through an API node.

From an image request to a fileA product accepts a prompt and references, then uses either a hosted model or a downloaded local model before saving the output.Prompt and referenceimagesProduct or workflowHosted model throughan APIDownloaded model onyour computerGenerated imageReview and preparethe asset

When comparing tools, ask which model runs, where it runs, what inputs it receives, and what you can save afterward.

How image generation works

You don’t need to understand the mathematics to use an image model. A little background helps explain why some controls matter and why certain requests fail.

Training and generation are separate

During training, a model learns patterns from a dataset. Depending on the system, that can involve images, captions, editing examples, and other kinds of data.

During inference, you use the trained model to produce an output. Your prompt and any reference images guide that output.

Asking for a new image doesn’t normally train the model for your project. Uploading a reference and training a personalized model are different operations.

A service’s policy on retaining uploads or using them for future training is another question. Check that policy separately.

Diffusion and latent space

A diffusion model learns to reverse a process that adds noise to data. During generation, it starts from a noisy state and repeatedly updates it toward an image, guided by your input.

Many systems do this work in a compressed representation called latent space. A decoder then turns that representation into pixels. The latent diffusion paper explains this approach.

A latent isn’t a tiny finished photograph that gets enlarged. It contains learned features that the decoder uses to reconstruct an image.

The model’s training resolution, latent representation, and implementation affect the sizes it can generate well. This is why entering an arbitrary width and height can give poor results or an error.

A simplified latent image generation pipelineText becomes conditioning information, which guides repeated updates to noisy latents. A decoder turns the final latent representation into pixels.Text promptText encoderRepeated updatesguided by the promptNoise from a randomseedFinal latentrepresentationImage decoderPixels saved as animage

This is one common pipeline. It doesn’t describe every image model.

Flow matching and transformers

Many newer systems use flow matching, which learns how to move between a simple noise distribution and the distribution of real data. The flow matching paper describes the general method.

For a user, the familiar controls can remain: a prompt, a seed, a sampling schedule, and a number of steps. Underneath, the training objective and update procedure can differ from older diffusion systems.

A transformer is a neural network architecture. Seeing that word in a model description doesn’t tell you whether the system generates text, denoises image latents, or uses another approach.

“Diffusion” and “transformer” can describe different parts of the same model.

Multimodal image models

A multimodal system works with more than one kind of input or output, such as text and images. Some accept a conversation with several reference images and return an edited image.

This can make the interface easier to use. You can explain a relationship between objects or refer to something in an uploaded photograph.

However, multimodal doesn’t reveal the full generation architecture. A company might publish the input and output behavior without disclosing the implementation.

Judge the documented capabilities and the results you get. Avoid assuming a model must use a particular internal design because its interface looks like a chat.

Why objects and lettering still go wrong

The system generates a plausible visual result. It doesn’t automatically maintain the rules of every object it draws.

A bicycle has a structure: two wheels, a frame joining specific points, pedals, a chain, and a handlebar connected to the steering assembly. A generated bicycle can look convincing at a glance while getting several connections wrong.

Text has a similar problem. Recognizable lettering and correct spelling require the model to produce the right visual marks in the right order. Language understanding alone doesn’t guarantee that.

Count objects, follow connections, and read every word. For instructions, prices, technical diagrams, and other exact information, use editable text or draw the required structure yourself.

The hosted models and products

The following sections describe what each route offers. They aren’t a quality leaderboard. Model access changes, and a product’s subscription can expose different features from its developer API.

OpenAI: ChatGPT and GPT Image

ChatGPT is the conversational route. Ask for an image, upload a reference, and describe the changes you want. It’s a convenient place to try our Officina brief without writing code.

GPT Image is the model family available through OpenAI’s developer platform. The current image generation guide distinguishes Sunburst for editing precision and Flare for everyday generation. The exact API model IDs appear in the code examples below.

The Image API provides generation and editing endpoints. The Responses API can include image generation as a tool in a larger conversation or agent workflow.

Those are separate choices. A model that coordinates a Responses conversation and the image model selected inside its image generation tool need not have the same name.

The API exposes output settings such as size, quality, and format. Supported GPT Image models also offer transparent output. A transparent PNG can be useful for a cutout, but you still need to inspect its edges.

A ChatGPT subscription and API billing are separate. Check access and billing in the service you intend to use.

For Officina, start with a generated illustration, then try changing only the bicycle’s color. Compare both versions carefully. An apparently small edit can alter nearby geometry or background details.

Google: Gemini and Nano Banana

Google uses Nano Banana as the name for Gemini’s native image generation capabilities. The official guide lists the available models and their API names.

At the documentation check for this article, the family includes Nano Banana 2.1, a Lite option, and Nano Banana Pro. They have different priorities around speed, complex tasks, and editing. Don’t assume the cheapest variant supports the same reference workflow as another one.

Gemini’s image workflows accept text and reference images and support conversational changes. The guide documents aspect ratios and output resolution options, with support depending on the selected model.

Google says generated images include a SynthID watermark.

You may also encounter Imagen in older tutorials. Google’s Gemini API Imagen page says those models have shut down in that API and directs readers to Nano Banana. That statement concerns the Gemini API; check the separate documentation for another Google service you’re using.

For our bicycle illustration, test whether an edit preserves the original composition across several turns. Save a copy of the first acceptable image so you can return to it.

Black Forest Labs: FLUX

FLUX spans hosted and downloadable models. The family name alone doesn’t tell you whether a particular model can run locally or what license applies.

The FLUX Image documentation describes generation, instruction-based editing, multiple reference images, and bounding boxes for composition.

Bounding boxes let you describe where elements belong. That is useful for a homepage illustration where we want the bicycle on the right and space for a heading on the left.

The smaller FLUX Image Klein model has downloadable weights. Its documentation also calls out prompt upsampling: another model expands a short request into the detailed caption expected by the generator.

That extra stage has practical consequences. It can change the prompt, require additional memory, and complicate an otherwise small local pipeline. Check the workflow supplied for your runner rather than downloading only the main weight file.

Hosted FLUX 3 Image searches the web by default. Set grounding to false when the picture should use only your prompt and reference images.

A useful way to compare hosted systems

Compare products against one brief and set of references, with written acceptance criteria. Keep each product’s syntax separate.

For Officina, a useful evaluation is:

  1. Generate the initial illustration.
  2. Change the bicycle from blue to green.
  3. Replace the repair stand with a small toolbox.
  4. Extend the canvas to create more room on the left.
  5. Export the image and inspect it at its intended display size.

Record whether each step succeeded and how many attempts it needed. A beautiful first image tells you little about the editing workflow.

Avoid declaring a model “best at text” or “best at realism” from one example. You might discover it works well for short English signs but struggles with your language or type of layout.

Create the first Officina illustration

Open an image-capable chat product or a creative tool with text-to-image generation. Choose a landscape aspect ratio if the interface offers it.

Enter our brief from the beginning of the article. Generate a small set of alternatives, within the budget you’re comfortable spending.

Review the images against the brief before asking for more detail.

Does the bicycle sit on the right? Is the left side quiet enough for a heading? Are the wheels circular, and does the frame make sense? Is there accidental lettering?

If all candidates have a cluttered background, change the composition instruction. Adding more style adjectives probably won’t fix the missing empty space.

A more explicit follow-up is:

Keep all bicycle and workshop objects inside the right two-thirds of the canvas. Leave the entire left third as uninterrupted pale cream. Remove any wall decorations or signs.

This identifies an observable change. “Make it more professional” leaves the model to guess what you dislike.

Save the candidate you want to keep before continuing.

Prompt for the medium and composition

The same subject can become a photograph, a watercolor, a flat illustration, or a product rendering. Specify the medium when it matters.

For a photograph, describe the viewpoint, light, materials, and surroundings. For an illustration, describe the line work, fills, palette, and amount of detail.

For Officina, “flat editorial illustration, dark outlines, four main colors, minimal shading” is more useful than “stunning masterpiece, ultra-detailed, 8K.”

Asking for “8K” in a prompt doesn’t set the file’s dimensions. Use the actual output controls.

A long prompt is useful when its details resolve ambiguity. Repeating the same requirement in several ways can add noise. Midjourney’s prompting guide, for example, recommends concise descriptive prompts rather than long instruction lists.

Adapt the brief to the product. A chat editor can handle a sequence of instructions differently from a text-to-image model expecting a scene description.

Use references deliberately

A reference image can supply composition, identity, style, or a specific object. Explain how you want the model to use it.

If we upload a rough sketch, our instruction might be:

Use this sketch for placement. Keep the large empty area on the left. Replace the rough bicycle drawing with a flat editorial illustration. The sketch’s colors are only guides and should not appear in the final image.

If we supply two references, explain their roles individually. “Use the layout from image one and the palette from image two” is clearer than “combine these.”

A reference influences the result according to the model and controls. It doesn’t guarantee exact preservation.

For a real shop’s product photos, compare the result with the original before using it commercially. A model can invent a component or remove a distinguishing mark while making the image look cleaner.

Separate exploration from finishing

Explore the subject and composition at a cheaper or faster setting. Once the design works, use the output quality and resolution needed for the final asset.

A higher quality setting can improve rendering, but it won’t reliably repair a badly specified layout. It can also change details, so review the final output again.

Keep the accepted image, its prompt, and the settings together. A chat history alone is awkward to use as an asset library.

Editing images without starting over

Editing covers several operations, and tools often use the same word for different workflows.

Instruction-based editing

You provide an image and describe a change.

For Officina:

Change the blue bicycle frame to dark green. Preserve the wheel positions, the repair stand, the background, and the empty area on the left.

Inspect those preservation requirements afterward. “Keep everything else unchanged” is an instruction whose success you need to check.

If preserving the exact original pixels is required, composite the accepted region in an editor or use a workflow with explicit pixel preservation.

Inpainting

Inpainting fills or changes a selected region, usually described by a mask. We could mask the toolbox to replace it with a different one.

Mask conventions vary. Some workflows use white for the editable area; some APIs use transparent mask pixels. Follow the tool’s documentation.

Include enough surrounding area to let the replacement join naturally. A mask cropped tightly around an object can leave awkward edges or inconsistent shadows.

Some generative editing APIs treat masks as guidance and can still change other regions. Compare the output with the source when that matters.

Outpainting

Outpainting extends an image beyond its existing edges. It’s useful if our accepted illustration needs more room for the headline.

Place the original on a larger canvas and generate the missing region using a supported expansion workflow. The model needs to continue the background coherently across the old boundary.

A request to “make it wider” can instead crop or recompose the image. Check which operation the interface performs.

Upscaling

An ordinary resize interpolates pixels. A generative upscaler can synthesize detail.

That can improve an illustration’s appearance, but it can also invent spokes, change a logo, or add texture that wasn’t present.

Compare at 100% zoom and at the intended display size. Upscaling a structurally wrong bicycle can give you a more detailed wrong bicycle.

Background removal and transparency

A checkerboard drawn inside a picture is still part of the picture. Real transparency requires an alpha channel.

If a generator supports transparent output, select it through the interface or API. Otherwise, use a background removal tool or make a mask in an editor.

Look for halos, missing thin parts, and partially transparent edges. Bicycle spokes are a good stress test.

Save transparency in a format that supports it, such as PNG or WebP. JPEG doesn’t preserve an alpha channel.

Creative tools beyond the chat apps

A creative application can save you work even when it uses a model you can access elsewhere. Selecting regions, keeping references beside the canvas, editing text, and exporting a finished design all take time.

Midjourney

Midjourney is a hosted creative product with its own models. It gives you a workflow for exploring images, making variations, and steering appearance through references and generation parameters.

Try it when you want to explore a visual direction and choose from alternatives. Learn its own prompt and reference controls rather than copying settings from Stable Diffusion.

There is an automation boundary to know about. Midjourney’s community guidelines say it doesn’t provide a general API, apart from rare explicitly granted exceptions. A service advertising a “Midjourney API” needs separate scrutiny.

Also check visibility before uploading private material. Midjourney is open by default. Its Stealth documentation explains which plans offer privacy controls and why posting in a public Discord channel remains public.

Adobe Firefly

Adobe Firefly is both an Adobe model family and a creative application. Adobe also offers Firefly Services APIs.

The application includes partner models as well as Adobe’s own models. Check which one you’ve selected before attributing an output or applying a claim about its training data.

The appeal is the surrounding editing workflow, especially if you already finish images in Photoshop, Illustrator, or Express. Generate an element, adjust its placement, and complete the design with ordinary editing tools.

Ideogram

Ideogram develops image models and offers a creative application and API. Typography is a particular focus.

Try it with short, exact text and the layout you need. Check the output letter by letter, including punctuation. Text rendering quality doesn’t remove the need for proofreading.

Ideogram also offers downloadable weights for a specific model release. Its licensing page distinguishes public noncommercial weights from commercial self-hosting arrangements. The license on inference code doesn’t automatically cover the model weights.

Recraft

Recraft offers a design application and APIs for raster and vector generation.

The distinction matters. A raster illustration with smooth shapes is still a grid of pixels. A generated SVG can contain editable vector paths.

If you need icons that scale cleanly or artwork you can adjust in a vector editor, test the actual vector workflow. Open the exported SVG and inspect its paths. A vector file can still contain excessive complexity or unwanted elements.

Recraft’s Studio rights documentation distinguishes free and paid output rights and visibility. Check the terms for the plan and interface you use.

Leonardo, Canva, and Krea

Leonardo combines its own models with external ones and supplies editing, upscaling, and custom-model workflows. Compare the specific model and operation, rather than treating all Leonardo outputs as one model’s work.

Canva is useful when the finished deliverable is a design. Generate an illustration, then add the heading, layout, and other elements in the editor. Our Officina poster would benefit from keeping its wording editable there.

Krea combines image models with creative interfaces, including realtime and enhancement tools. Its current generation model and its downloadable model offering are separate choices. Confirm the model when moving between the app, API, and a local runner.

Freepik and Magnific

The current Magnific homepage says “Freepik is now Magnific.” You may encounter both names in tutorials and older recommendations.

The platform brings together stock assets, multiple generation models, editing, upscaling, and visual workflows. Its value depends on which parts of that process you need in one place.

A desktop interface for a service doesn’t establish that inference happens on your computer. Check where the chosen operation runs.

xAI, Meta, and ByteDance

xAI’s Grok Imagine image API supports generation and editing. Treat the image model separately from Grok’s language models. Download outputs promptly if you’re using temporary result URLs.

Meta’s Muse Image appears in Meta AI. Meta describes using it with Muse Spark for planning and context, including edits based on photos and annotations. App availability depends on the rollout.

You can also call Muse Image on the Meta Model API. The model ID is muse-image-1.0, and the API covers generation and editing. The docs list it as a hosted model. Muse Spark Open, the downloadable release, is a text model.

ByteDance’s Seedream is an image model family; Dreamina is a user-facing creative application. The model documentation describes generation, reference-based work, and editing. Its examples are useful starting points for an evaluation, but still inspect factual diagrams and product details yourself.

Microsoft Designer

Microsoft Designer combines image generation with layouts and editing tools. Related capabilities also appear in Microsoft’s Copilot products. Treat those as product interfaces; don’t assume every image operation across them uses the same underlying model.

Designer is another route for finishing a poster or social image with editable layout elements around generated artwork.

Amazon Nova Canvas

Amazon Nova Canvas reached end of life on September 30, 2026. Calls to amazon.nova-canvas-v1:0 fail. The older user guide still describes reference conditioning, inpainting, outpainting, and background removal.

The Bedrock catalog can still list a retired model. Read the model card for the ID you plan to call.

What about Claude?

Anthropic says Claude doesn’t directly generate photos or illustrations like a raster image generator. It can analyze images and create visuals through code, including HTML and SVG.

Claude can also coordinate a workflow that calls an external image tool. In that case, check which image model the tool invokes and how it is billed. The agent and image generator have separate roles.

How I would choose among these tools

For a one-off illustration, I would start with an image product I already have access to. I’d test composition and editing before paying for another subscription.

For a poster, I would favor a workflow that lets me finish the typography and layout in an editor. For an automated application feature, I would narrow the list to documented APIs.

For exact diagrams and interface icons, I would first consider SVG or ordinary drawing code. Generating the final structure from code lets me position every connection and keep every label editable. On this site, for example, the blog stack overview describes an approach built around reusable publishing tools; I would keep repeatable site assets in that kind of workflow.

A model can still help with a sketch or visual direction. Whether it should produce the finished file depends on how much precision the asset needs.

Run image models on your computer

Local generation means the selected model performs inference on your machine. You download the weights and use software that knows how to run them.

This removes per-call fees from a hosted provider. You still pay through hardware, electricity, disk space, and your time. Some models also require a license for your intended use.

Local generation is useful for repeated experiments, working offline, or keeping sensitive image inputs within a controlled environment.

It requires more setup. You need a compatible model, enough memory for its whole pipeline, and a runner that supports your hardware.

Choose the software first

SoftwareInterfaceWhere I would start
Draw ThingsNative Apple app with a canvas and model controlsLocal image work on a Mac, iPhone, or iPad
DiffusionBeeMac applicationAn approachable local Stable Diffusion workflow
ComfyUIVisual graph of connected nodesReusable pipelines and model-specific workflows
InvokeLocally hosted creative interfaceCanvas-based editing with supported models
MFLUXTerminal commands and Python APIApple Silicon generation and automation
stable-diffusion.cppInference engine and command-line toolsDeveloper workflows across supported backends
DiffusersPython libraryBuilding or adapting an image pipeline in code

Support differs between tools and releases. A model being downloadable doesn’t mean every runner can load it.

Draw Things also offers optional cloud computation. ComfyUI has remote API nodes. Choose local operations throughout the workflow when local inference is your requirement.

For general background on weights, quantization, and choosing a model, the free Local AI Models Course covers those concepts. Its application examples concern language models; image generation needs the image-specific software shown here.

Choose a model that fits the workflow

SDXL remains useful because there are established tools, checkpoints, and adapters around it. It is a reasonable family for learning a classic text-to-image workflow. Its base model card explains the optional refiner and the applicable license.

Stable Diffusion 3.5 is another downloadable family. Read the specific model card and its Stability license instead of assuming all Stable Diffusion releases share identical terms.

FLUX offers several downloadable variants. Older Schnell weights, some Klein releases, and other FLUX variants have different licenses and resource requirements. For example, FLUX.2 Klein 4B uses Apache 2.0, while FLUX 3 Image Klein uses the FLUX Kommunity License.

Qwen Image includes generation and editing models. The original Qwen Image and Qwen Image 2.1 have different licenses. The newer model also supports native RGBA output. Confirm both runner support and the license for the exact checkpoint.

Z-Image Turbo is a compact, distilled option supported by MFLUX and ComfyUI. The official project supplies its intended sampling settings. We’ll use it for our terminal example.

Downloadable releases also exist from developers such as Ideogram and Krea. They broaden the local choices, but each release still needs a compatible runner and an acceptable license.

Large downloadable models can be server projects. HunyuanImage, for example, documents multi-GPU reference configurations. Its license also has territorial restrictions. It isn’t a general laptop recommendation.

Understand the memory requirements

On a typical discrete-GPU PC, VRAM is the memory on the graphics card. System RAM is separate. A machine with lots of RAM can still run out of VRAM.

Apple Silicon uses unified memory, shared by the CPU, GPU, operating system, and applications. The number printed on the box isn’t all available to your generation job.

The main model weights are only part of the requirement. A pipeline can also need text encoders, a decoder, image encoders, and working memory for the generated image.

Higher resolutions, larger batches, multiple references, and extra control models can increase memory use.

Quantization reduces the precision used to store some model values. This can reduce memory requirements, with tradeoffs that depend on the model and implementation.

Offloading moves parts of the work or weights between memory locations. It can make a workflow fit while adding transfers and slowing it down.

Use the hardware guidance for your exact runner and workflow. Invoke’s requirements, for example, give different recommendations for SDXL, FLUX, and quantized Z-Image. Those figures describe Invoke’s supported configurations.

Don’t buy a GPU based only on a model’s parameter count or download size. Check a complete workflow on similar hardware, including its encoders and target resolution.

Local walkthrough with Draw Things

For an Apple device, Draw Things provides an application-based route without assembling a Python environment yourself.

Install the official application and choose a model from its supported catalog that suits your device. Check the download size, license, and required components before starting.

Use local generation for this exercise. If you select a cloud option, the computation happens remotely.

Enter the Officina prompt and choose a landscape canvas supported by the model. Begin with one image and the model’s recommended settings.

Generate the illustration, then save it with its settings. Change one part of the prompt, such as the bicycle’s color, and generate another version.

At this stage, we’re learning what the model does with text. Matching seeds can help compare settings in a fixed workflow, but a changed prompt can still change the whole composition.

For a targeted change to the accepted image, use the application’s supported image editing or masked workflow. Generating again from text is a different experiment.

If generation fails from insufficient memory, reduce the resolution or choose a lighter supported model. Starting several simultaneous jobs can make the problem worse.

Local walkthrough with MFLUX on a Mac

MFLUX runs image models using Apple’s MLX framework. Its command-line interface is useful when you want to save commands and repeat jobs.

This route assumes an Apple Silicon Mac and enough available memory for the chosen model. The project README documents supported models and installation requirements.

Install uv if you don’t already have it, then install MFLUX in its own tool environment:

uv tool install --upgrade mflux

The first generation downloads model files. Allow disk space for those files as well as your outputs. Review any model access or license requirements before downloading.

The following command adapts the project’s documented Z-Image Turbo example to our illustration:

mflux-generate-z-image-turbo \
  --prompt "Flat editorial illustration of one blue city bicycle on the right, small repair stand behind it, pale cream background, dark outlines, limited palette, empty left third, no lettering" \
  --width 1280 \
  --height 768 \
  --seed 42 \
  --steps 9 \
  -q 8

-q 8 selects 8-bit quantization in this command. It doesn’t mean eight images or an output quality rating.

The command reports where it saves the image. Review the result before generating a batch. If it fails to fit, check MFLUX’s supported quantization options and choose a configuration that fits your Mac.

Keep a copy of the command. To explore alternatives, change only the seed and compare the outputs. To investigate a prompt change, keep the rest of the workflow fixed.

Don’t copy the step count and guidance from this model into an unrelated one. Distilled models have their own intended settings.

Local walkthrough with ComfyUI

ComfyUI represents an image pipeline as a graph. Each node loads data, transforms it, runs a model, or saves an output.

The graph can look complicated because it exposes steps an application usually hides. You can start from a maintained template rather than building every connection yourself.

Install and load a supported template

Choose the official installation for your operating system and GPU. Follow its hardware instructions instead of installing a random collection of GPU packages from an old tutorial.

Open the workflow templates and select a text-to-image example for a model your machine can run. For learning the classic workflow, use a supported SDXL template and follow its model download instructions.

The template should tell you which files it needs and where they belong. Some models package their components in a checkpoint; others use separate files.

ComponentPurpose
Checkpoint or diffusion modelThe main generation weights
Text encoderConverts the prompt into model conditioning
VAE or other image decoderConverts a latent result into image pixels
LoRAAdds a learned adaptation to compatible components
Control modelConditions generation on structure such as edges or depth
UpscalerEnlarges or refines the selected output

Only install the components the chosen workflow requires. A missing text encoder won’t be fixed by downloading another unrelated checkpoint.

Follow the image through the graph

A classic SDXL graph contains these logical stages:

A classic ComfyUI text-to-image workflowA checkpoint supplies model components. Prompt conditioning and an empty latent feed a sampler, then a decoder and save node produce the image file.Load checkpointEncode promptSamplerEmpty latent withchosen dimensionsDecode latentsSave image

The template handles the actual connections. Newer models can require different nodes, separate encoders, or different sampling logic.

Enter the Officina prompt in the positive prompt node. If the template includes negative conditioning, keep it simple and use it only as supported by that model.

Choose a landscape size within the template’s recommendations. Start with a batch size of one and the supplied sampling settings.

Run the workflow. The saved image should appear in its output node. If you get a missing-model error, check the exact filename and destination requested by the template.

Save a reproducible workflow

Export the workflow JSON and keep it with the accepted image. ComfyUI can also save workflow metadata in supported output files and reload it from them.

Metadata can disappear when an image is converted or uploaded, so keep the JSON separately.

For each accepted asset, record the model files, seed, dimensions, sampling settings, adapters, and any reference images. If you need to reproduce old results, preserve the actual files or identify their hashes.

A seed alone doesn’t preserve a workflow. Different model revisions, sampling algorithms, libraries, and hardware can change the result.

Keep local workflows local

Inspect the graph before using private references. A paid partner node can send data to a remote service even while ComfyUI itself runs locally.

Custom nodes are executable software. Install ones you need from maintainers you trust. An unfamiliar workflow that requests many custom extensions deserves inspection before installation.

The ComfyUI repository documents offline and API-node controls. Those controls help with built-in functionality; separately review third-party extensions.

The controls you will encounter

Local tools expose more controls than most chat products. Some settings also appear in hosted APIs, but they aren’t standardized across models.

Seed

The seed initializes the random process used by the generator. It helps compare runs within a fixed setup.

Keep the seed constant while changing one setting to make the comparison easier. Change the seed when exploring alternatives.

Identical seeds don’t guarantee identical files across implementations or model revisions. A seed also doesn’t preserve character identity when you change the scene.

Steps and sampling schedule

Sampling steps are the updates used to produce the image. More steps mean more work, but the visual result doesn’t improve indefinitely.

A distilled model is trained to work with a shorter sampling process. Using a large step count copied from another model can waste time or produce worse output.

The sampler and scheduler determine how those updates proceed. Begin with the model’s maintained example. Adjust them when you have a specific problem to solve.

Guidance

Guidance influences how conditioning steers generation. In classic classifier-free guidance, the process combines conditioned and unconditioned predictions.

A higher value can push the result toward the prompt while also causing harsh contrast, unusual colors, or other artifacts.

There is no universal “good guidance” number. Some models use a different guidance mechanism or expect it to be disabled. The same numeric value can mean different things across pipelines.

Negative prompts

A negative prompt specifies unwanted visual features in models that support negative conditioning.

It can help with particular compositions, but a large inherited list of unwanted features isn’t a general repair tool. It can also interfere with things you do want.

Start with the supplied workflow and a small, relevant negative prompt if supported. Don’t assume a chat product has a hidden equivalent you can control by writing “negative prompt” in a message.

Image strength

Image-to-image workflows often add noise to an existing image and regenerate from it. A strength control determines how far that process can move from the source.

Lower strength commonly preserves more of the input; higher strength permits larger changes. Exact definitions depend on the implementation.

A lower strength can preserve an unwanted mistake too. If the bicycle frame is structurally wrong, preserving most of the original may keep that error.

ControlNet, adapters, and LoRAs

Prompt wording is only one way to guide a model.

A ControlNet or related control model can condition generation on structure, such as an edge map, depth map, or pose. The Diffusers ControlNet guide shows the idea and supported pipelines.

For Officina, a sketch could fix the approximate wheel positions and frame outline while the generator develops the illustration style.

An image-reference adapter can supply visual conditioning from a reference image. Different adapters preserve different aspects of that image. Check the adapter’s purpose and the compatible base model.

A LoRA is a compact learned adaptation. You can use one trained for a visual style or subject, or train your own with suitable images and captions. The Diffusers training guide explains this route.

These tools solve different problems:

You need to preserveA control to investigate
The composition of a drawingEdges, depth, or another structural control
The appearance of a referenceA supported reference adapter or image editing model
A recurring learned style or subjectA compatible LoRA
Exact lettering and placementText layout or drawing code
Unchanged pixels outside a regionMasked compositing with explicit preservation

Compatibility matters at the architecture level. An SDXL LoRA won’t become a FLUX LoRA because you put it in the same folder.

A stronger LoRA weight can exaggerate the learned style or distort the subject. Test it with several prompts before relying on it for a batch.

Train only when a reference workflow and ordinary prompting aren’t enough. Training adds dataset preparation, compute requirements, and another artifact to maintain.

Generate images from JavaScript

An API is useful when generation becomes part of your application or repeatable workflow. We’ll start with small Node.js scripts.

These examples use Node’s built-in fetch, file APIs, and, for editing, FormData. Use a current Node release with those APIs available.

Create a working directory:

mkdir officina-images
cd officina-images

Make your provider’s API key available through the corresponding environment variable. Keep keys out of source files and browser code. API access can require billing setup or account verification.

Every generation call can incur a charge. Run one request at a time while learning the response format.

Generate with OpenAI

We’ll send our illustration brief to the Images API and save the returned PNG. This follows the official image generation endpoint.

Make OPENAI_API_KEY available in your shell. Save this complete file as generate-openai.mjs:

import { writeFile } from 'node:fs/promises'

const apiKey = process.env.OPENAI_API_KEY
if (!apiKey) throw new Error('Set OPENAI_API_KEY before running this file')

const model = 'gpt-image-2.5-flare'
const prompt = 'Flat editorial illustration of one blue city bicycle on the right, a small repair stand behind it, pale cream background, dark outlines, limited palette, empty left third, no lettering'

const response = await fetch('https://api.openai.com/v1/images/generations', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model,
    prompt,
    n: 1,
    size: '1536x1024',
    quality: 'low',
    output_format: 'png'
  }),
  signal: AbortSignal.timeout(120_000)
})

if (!response.ok) throw new Error(`Image request failed: HTTP ${response.status}`)

const result = await response.json()
const image = result.data?.[0]?.b64_json
if (!image) throw new Error('The response contained no image')

await writeFile('officina.png', Buffer.from(image, 'base64'))
await writeFile('officina.json', JSON.stringify({
  model,
  prompt,
  size: '1536x1024',
  quality: 'low',
  usage: result.usage
}, null, 2))

Run it:

node generate-openai.mjs

The script saves officina.png and a small metadata file. It requests a supported landscape size; we’ll prepare the exact website dimensions later.

The timeout limits how long our script waits. It doesn’t establish that a timed-out request was canceled on the provider’s servers or won’t be billed.

If you get an access error, check the model’s availability and your API account. Changing your ChatGPT subscription doesn’t configure API billing.

Edit the generated image

Now we’ll upload the generated PNG and request a green frame. The edit endpoint accepts multipart form data.

Save this as edit-openai.mjs in the same directory:

import { readFile, writeFile } from 'node:fs/promises'

const apiKey = process.env.OPENAI_API_KEY
if (!apiKey) throw new Error('Set OPENAI_API_KEY before running this file')

const bytes = await readFile('officina.png')
const form = new FormData()
form.set('model', 'gpt-image-2.5-sunburst')
form.set('prompt', 'Change only the blue bicycle frame to dark green. Preserve the composition, wheels, repair stand, pale cream background, and empty left third.')
form.set('image', new Blob([bytes], { type: 'image/png' }), 'officina.png')
form.set('output_format', 'png')

const response = await fetch('https://api.openai.com/v1/images/edits', {
  method: 'POST',
  headers: { Authorization: `Bearer ${apiKey}` },
  body: form,
  signal: AbortSignal.timeout(120_000)
})

if (!response.ok) throw new Error(`Image edit failed: HTTP ${response.status}`)

const result = await response.json()
const image = result.data?.[0]?.b64_json
if (!image) throw new Error('The response contained no edited image')

await writeFile('officina-green.png', Buffer.from(image, 'base64'))

Run it after the generation script:

node edit-openai.mjs

We let fetch set the multipart content type and boundary. Setting Content-Type: application/json here would be wrong.

This is an instruction-based edit without a mask. Compare officina-green.png with the source before accepting it.

Generate with Google’s Gemini API

Google’s current image generation guide uses the Interactions API for its main examples. We’ll use that API directly so the request and response are visible.

Make GEMINI_API_KEY available in your shell. Save this as generate-gemini.mjs:

import { writeFile } from 'node:fs/promises'

const apiKey = process.env.GEMINI_API_KEY
if (!apiKey) throw new Error('Set GEMINI_API_KEY before running this file')

const model = 'gemini-nano-banana-2.1'
const prompt = 'Create a flat editorial illustration of one blue city bicycle on the right, a small repair stand behind it, pale cream background, dark outlines, limited palette, empty left third, no lettering'

const response = await fetch('https://generativelanguage.googleapis.com/v1beta/interactions', {
  method: 'POST',
  headers: {
    'x-goog-api-key': apiKey,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    model,
    input: prompt,
    response_format: {
      type: 'image',
      mime_type: 'image/png',
      aspect_ratio: '16:9',
      image_size: '1K'
    }
  }),
  signal: AbortSignal.timeout(120_000)
})

if (!response.ok) throw new Error(`Image request failed: HTTP ${response.status}`)

const result = await response.json()
const image = result.steps
  ?.filter(step => step.type === 'model_output')
  .flatMap(step => step.content ?? [])
  .findLast(content => content.type === 'image' && content.data)
if (!image?.data) throw new Error('The response contained no image')
if (image.mime_type !== 'image/png') throw new Error('Expected a PNG image')

await writeFile('officina-gemini.png', Buffer.from(image.data, 'base64'))
await writeFile('officina-gemini.json', JSON.stringify({
  interactionId: result.id,
  model,
  prompt,
  usage: result.usage
}, null, 2))

Run it:

node generate-gemini.mjs

The REST response contains steps, so we find an image inside a model output step. The SDK has convenience accessors that differ from this raw response.

An API can return a refusal, text, or an otherwise incomplete result instead of an image. The script checks before trying to decode image data.

For conversational follow-ups, the documented API supports previous_interaction_id. For edits based on a local image, supply an image input with its MIME type and base64 data. Follow the input format for the API you use; older generateContent examples have a different response shape.

Other APIs and hosted open models

You can call a model’s developer directly or use a platform that hosts models from several developers.

Replicate and fal offer hosted model execution. OpenRouter offers image generation through supported models in its API.

These routes let you try a model without operating a GPU server. They can also give you access to multiple model families through one account.

Check the exact endpoint’s inputs, license, output format, and billing. A common API envelope doesn’t make every underlying model support masks, seeds, or arbitrary dimensions.

Some endpoints return an image immediately. Others return a job ID or polling URL. Some image URLs expire, so copy accepted results to your own storage.

Keep provider-specific handling in a small adapter when your application uses several services. Preserve capability differences in that adapter instead of silently ignoring unsupported options.

Prepare the image for a website

A generated image is a source asset. Prepare a separate delivery file for the site.

We’ll use Sharp to create a 1600 × 900 WebP. This operation fits the entire illustration inside that size and fills any remaining space with a light background.

Install Sharp in the example directory:

npm init -y
npm install sharp

Save this as prepare.mjs:

import sharp from 'sharp'

const input = process.argv[2] || 'officina.png'

await sharp(input)
  .rotate()
  .resize(1600, 900, {
    fit: 'contain',
    background: '#fcfcfa'
  })
  .webp({ quality: 85 })
  .toFile('officina-web.webp')

Run it:

node prepare.mjs officina-green.png

This prepares the edited candidate. For the Google example, run node prepare.mjs officina-gemini.png. With no filename argument, the script uses officina.png.

fit: 'contain' preserves the whole image and can add padding. If you choose cover instead, Sharp fills the frame and crops the excess. Check where the crop cuts the wheels and the empty area for text.

This resize doesn’t add meaningful new detail. If the source is too small for your intended use, generate at a suitable resolution or evaluate an upscaler first.

On the page, use a real heading over or beside the illustration. Give the image explicit dimensions to reserve layout space. If it only decorates information already present in the text, an empty alt attribute can be appropriate.

For meaningful images, describe what readers need to understand. Don’t make the alt text a copy of the generation prompt.

Consistent characters, products, and asset sets

Generating a set of images adds requirements that a single image doesn’t have.

Our bicycle should keep the same frame, wheel proportions, and palette if it appears across several pages. A character needs to remain recognizable through different poses and expressions.

Start from an accepted reference. Keep a short list of properties that must remain stable and use it in every request.

For Officina, that might be a dark blue step-through frame, cream tires, a brown saddle, dark outlines, and minimal shading.

Use a supported reference workflow or a compatible learned adaptation when needed. A shared seed can make some comparisons easier, but it doesn’t encode the subject’s identity.

Review the images as a set, side by side. Differences in scale, lighting, or line thickness are easier to see that way.

If exact product geometry matters, use product photography, compositing, or a 3D render as the foundation. Let the generator assist with the surrounding scene only where that preserves the facts of the product.

Pixel art and sprites need extra work

A general image model can produce artwork that resembles pixel art. That doesn’t guarantee a useful sprite.

A game asset can need a fixed logical grid, a limited palette, clean transparency, a shared origin point, and consistent proportions between animation frames.

Check the grid and palette as well as how the subject looks.

If you reduce a large image to sprite size, nearest-neighbor scaling avoids blending neighboring colors. It won’t automatically fix inconsistent pixel clusters, mismatched outlines, or a poor pose.

Palette reduction can limit colors, but it can also destroy intentional shading. Grid snapping and palette cleanup need visual review afterward.

For sprite sheets, don’t assume the model respected the requested number of rows or columns. Validate the actual output before slicing. Automatically cropping each frame to its subject and resizing it independently can make the character grow and shrink during animation.

Keep a consistent frame canvas, scale, and anchor point. Check the animation in motion.

For strict retro constraints, a dedicated pixel-art tool or procedural drawing can be a better starting point. A coding model can help write a constrained renderer that uses a fixed grid and palette, while an artist controls the design.

The Hacker News discussion around Daniel Ball’s guide makes this distinction clear: a convincing large preview and a production-ready sprite are different deliverables.

Cost: measure accepted images

Services charge in different ways. The model’s billing unit may be an image, generated tokens, megapixels, GPU time, or subscription processing time.

Billing methodWhat to check
Fixed image priceWhich size and operation that price includes
Size and quality tiersInput charges, output tiers, and edit costs
Image tokensInput images, output token consumption, and quality
MegapixelsRounding, minimum charges, and input-image billing
Compute timeStartup, runtime, and whether idle time is charged
Subscription credits or GPU timeRate for each mode, limits, and overage behavior
Local executionHardware, power, licenses, maintenance, and elapsed time

A simpler scene isn’t necessarily cheaper. Many systems perform a similar amount of work for two images with the same settings, but some newer models use variable processing. Use the actual billing rules.

Reducing dimensions only saves money if the model supports the requested size and its pricing changes accordingly. “Make a small thumbnail” inside a prompt isn’t an output setting.

For current prices, check the provider’s own pages: OpenAI, Google, and BFL. Aggregator pricing can differ from a developer’s direct API.

For your evaluation, calculate:

Generation cost per accepted asset = total generation spend / accepted assets

Suppose one model costs $0.01 per attempt and you accept 2 images from 20 attempts. You spent $0.20, or $0.10 per accepted image.

Another costs $0.04 per attempt and you accept 4 images from 5 attempts. You also spent $0.20, or $0.05 per accepted image.

Those are hypothetical figures. They show why counting attempts matters. Track editing time separately, because a cheap image that needs twenty minutes of cleanup may be expensive for your project.

Build image generation into an application

Our scripts make one request and save one file. A user-facing service needs to manage a longer-running job.

A common design is:

An image generation job in an applicationThe server validates a request and creates a queued job. A worker calls the provider, stores the result, and updates the status. Failures lead to an explicit error state.User requests animageServer checks inputand budgetCreate a queued jobWorker calls imageproviderStore output andmetadataMark job completeRecord refusal orfailureClient displays theresultClient displays theerror

Return a job ID promptly and let the client follow its status. A platform that supports sufficiently long requests can handle some generations directly, but queueing becomes useful when work must survive client disconnects or be rate-limited.

Keep provider keys on the server. Limit who can generate, how many jobs they can queue, and how much they can spend.

Treat timeouts carefully. A provider may have finished and billed a request even if your connection failed before receiving the response. Use provider-supported idempotency or job lookup where available. Blindly retrying can buy the same operation twice.

Retry transient errors with bounded backoff. A content refusal or invalid parameter needs a different response from a temporary service failure.

Before marking the job complete, verify that an image exists and has an expected format and dimensions. Save it in storage you control when the provider returns temporary URLs.

Keep enough metadata to investigate problems: model identifier, operation, requested settings, actual output dimensions, duration, usage, and job status. Record prompts and reference details only under a retention policy appropriate to the data.

A request hash is useful for finding equivalent inputs, but it doesn’t mean you should always return a cached image. A user asking for another variation expects a new generation. Make reuse an explicit product choice.

When testing application logic, use fixed image responses. Keep paid provider checks separate and small. A test of your job state handling shouldn’t spend money on new images every time it runs.

Let a coding agent use an image model

A coding agent can help turn a brief into a prompt, call an image tool, inspect the result, and revise it.

The agent still needs an image generation capability. A language model that writes SVG or calls a tool isn’t necessarily generating raster images itself.

You can connect the capability through a script, a function tool, or an MCP server. The guide to building an MCP server explains how tools can expose operations to compatible clients.

Give the agent an explicit output directory and a budget. For example:

Create up to four candidate illustrations for the Officina brief. Save each candidate separately. Stop after four paid generation calls. Inspect the images for bicycle geometry and clear space on the left, then show me the candidates and describe any visible problems. Keep the originals.

A count limit is useful when generation cost is predictable. For workflows involving expensive edits, upscaling, or different models, also enforce a spending limit in the code that executes the tools.

Make sure the agent can inspect the saved image. A path tells it where the output exists, but it needs a supported image-reading operation to assess the pixels.

Use deterministic checks for dimensions, file format, alpha, and file existence. Visual review is still needed for taste, composition, and whether an illustrated object makes sense.

I would keep final selection under human control. An agent can check a brief and propose revisions, while I decide which image belongs on the page.

Licenses, privacy, and provenance

These questions apply to both hosted and local workflows, but they concern different parts of the process.

Check the exact model license

Downloadable weights can come with commercial restrictions, revenue thresholds, territorial limits, or conditions on redistribution and training.

The runner’s software license is separate. An MIT-licensed application can load a model with restrictive terms.

Read the model card and linked license for the exact variant. Don’t transfer permissions from one member of a family to another. If commercial use is important, check the hosted provider’s terms too.

Permission under a service or model license and copyright protection for the resulting image are separate questions. A product’s ownership language doesn’t establish exclusive rights in every output.

Know where references go

A photograph uploaded to a hosted editor leaves your machine. Check retention, training use, visibility, and deletion controls for the account and endpoint you’re using.

“Private project,” “not used for training,” and “not retained” describe different policies. Read the applicable one instead of treating those phrases as interchangeable.

For local work, inspect the whole pipeline. Downloads, remote prompt expansion, cloud nodes, extensions, and synced output folders can introduce network activity even when the main generator runs locally.

Preserve source files and attribution records

Keep the original references, accepted generation, edit history, and licenses needed for your project.

C2PA Content Credentials can record signed provenance information. They don’t establish that the depicted scene is true, and missing credentials don’t prove an image was generated.

Invisible watermarks and file metadata are different mechanisms. Google’s image guide documents SynthID for its generated images. Don’t assume another vendor uses the same mechanism.

Resizing, recompressing, or stripping metadata can affect provenance records. Check what your export pipeline preserves and keep the original files.

Troubleshoot the result you have

ProblemWhat I would check first
The model ignores the layoutGive explicit placement or a sketch; try supported structural controls
A small edit changes everythingUse the source image and a targeted editing workflow; compare unchanged regions
Text is wrongShorten it, proofread it, or move it into editable type
The same character keeps changingUse accepted references and a supported identity workflow
Local generation runs out of memoryCheck all components, resolution, batch size, precision, and competing apps
A local workflow is unexpectedly slowCheck offloading, backend support, and whether it fell back to the CPU
The output has fake transparencyInspect its alpha channel rather than the visible checkerboard
The API returns success but no pictureInspect the documented response for text, refusal, or missing output
A saved URL stops workingDownload the result to your own storage before it expires
An old command no longer worksCheck current model names, API deprecations, and the runner’s maintained example

For the first experiment, keep the scope small. Make one Officina illustration, save its settings, change the frame color, and prepare the accepted image for a page.

Then repeat that exercise through a second route if you need to compare it. You’ll have a concrete answer about the controls, cleanup, cost, and hardware your own project requires.

Tagged: AI · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about ai: