Generating and saving multiple images using img2img pipeline
In theStableDiffusionImg2ImgPipeline, you can generate multiple images by adding the parameternum_images_per_prompt. But what is the best way to save all those images to a directory? All the examples I can find show doing:image[0].save(“filename”)Do you have to do one at a time:image[0].save(“filename”)image[1].save(“filename”)image[2].save(“filename”)And so on?
2023-02-01T21:03:14Z
hi@mmcquadeyou could use pathlib to create a dir and then iterate over the images.like thisDIR_NAME="./images/"
dirpath = Path(DIR_NAME)
# create parent dir if doesn't exist
dirpath.mkdir(parents=True, exist_ok=True)
....
for idx, image in enumerate(output.images):
    image_name = f'{slugify(prompt)}-{idx}.png'
    image_path = dirpath / image_name
    image.save(image_path)full examplefrom diffusers import StableDiffusionPipeline, EulerDiscreteScheduler
import torch
from pathlib import Path
import re

def slugify(text):
    # remove non-word characters and foreign characters
    text = re.sub(r"[^\w\s]", "", text)
    text = re.sub(r"\s+", "-", text)
    return text

model_id = "stabilityai/stable-diffusion-2"

device = "cuda" if torch.cuda.is_available() else "cpu"
# Use the Euler scheduler here instead
scheduler = EulerDiscreteScheduler.from_pretrained(
    model_id, subfolder="scheduler")
pipe = StableDiffusionPipeline.from_pretrained(
    model_id, scheduler=scheduler, torch_dtype=torch.float16)
pipe = pipe.to(device)

DIR_NAME="./images/"
dirpath = Path(DIR_NAME)
# create parent dir if doesn't exist
dirpath.mkdir(parents=True, exist_ok=True)

prompt = "a photo of an astronaut riding a horse on mars"
negative_prompt = "blurry, dark photo, blue"
steps = 15
scale = 9
num_images_per_prompt = 5
seed = torch.randint(0, 1000000, (1,)).item()
generator = torch.Generator(device=device).manual_seed(seed)
output = pipe(prompt, negative_prompt=negative_prompt, width=512, height=512, num_inference_steps=steps,
             guidance_scale=scale, num_images_per_prompt=num_images_per_prompt, generator=generator)

for idx, image in enumerate(output.images):
    image_name = f'{slugify(prompt)}-{idx}.png'
    image_path = dirpath / image_name
    image.save(image_path)
2023-02-08T15:20:55Z
Works like a charm, thank you@radames
2023-02-08T16:05:49Z
Actually another question for this as I get the warning:You have passed 3 text prompts (prompt), but only 1 initial images (image). Initial images are now duplicating to match the number of text prompts. Note that this behavior is deprecated and will be removed in a version 1.0.0. Please make sure to update your script to pass as many initial images as text prompts to suppress this warning.   deprecate("len(prompt) != len(image)", "1.0.0", deprecation_message, standard_warn=False)Any insights on best practices for passing more than 1 image as theinit_image?
2023-02-08T19:20:22Z
ok@mmcquade, I think you’re talking about the Image to Image pipeline with init image right? here is an exampleAs you see, the number of initial images, prompts, and negative prompts are matching to make it work.Your warning message, is for when you are passing 3 different prompts but only one initial image, internally it makes[init_image]*len(prompt).The example below break things apart for you.from diffusers import StableDiffusionImg2ImgPipeline, EulerDiscreteScheduler
from pathlib import Path
from PIL import Image
import torch
import re
import requests


def slugify(text):
    # remove non-word characters and foreign characters
    text = re.sub(r"[^\w\s]", "", text)
    text = re.sub(r"\s+", "-", text)
    return text

model_id = "stabilityai/stable-diffusion-2"

images_url = ["https://s3.amazonaws.com/moonup/production/uploads/1675140495576-noauth.png",
              "https://s3.amazonaws.com/moonup/production/uploads/1675032939263-noauth.png",
              "https://s3.amazonaws.com/moonup/production/uploads/1673856328001-noauth.png"]
            
init_images = [Image.open(requests.get(url, stream=True).raw).convert("RGB").resize((758,768)) for url in images_url]

prompts = ["beautiful colorful flowr",
           "green city future mountain 3d sunrise skycrapers", 
           "rainbow beach, palm trees, neon, miami"]

negative_prompts = ["blurry, dark photo, blue",
                    "blurry, dark photo, blue",
                    "blurry, dark photo, blue"]

device = "cuda" if torch.cuda.is_available() else "cpu"
# Use the Euler scheduler here instead
scheduler = EulerDiscreteScheduler.from_pretrained(
    model_id, subfolder="scheduler")
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
    model_id, scheduler=scheduler, torch_dtype=torch.float16)
pipe = pipe.to(device)

DIR_NAME="./images/"
dirpath = Path(DIR_NAME)
# create parent dir if doesn't exist
dirpath.mkdir(parents=True, exist_ok=True)

steps = 20
scale = 9
num_images_per_prompt = 1
seed = torch.randint(0, 1000000, (1,)).item()
generator = torch.Generator(device=device).manual_seed(seed)
output = pipe(prompts, negative_prompt=negative_prompts, image=init_images, num_inference_steps=steps,
             guidance_scale=scale, num_images_per_prompt=num_images_per_prompt, generator=generator)

for idx, (image,prompt) in enumerate(zip(output.images, prompts*num_images_per_prompt)):
    image_name = f'{slugify(prompt)}-{idx}.png'
    image_path = dirpath / image_name
    image.save(image_path)