Unverified Commit b2fa0a92 authored by AUTOMATIC1111's avatar AUTOMATIC1111 Committed by GitHub
Browse files

Merge pull request #10838 from breengles/img2img-batch-processing

Img2img batch processing
parents 80ae378f ba110bf0
Loading
Loading
Loading
Loading
+25 −7
Original line number Diff line number Diff line
import os
from pathlib import Path

import numpy as np
from PIL import Image, ImageOps, ImageFilter, ImageEnhance, ImageChops, UnidentifiedImageError
@@ -13,7 +14,7 @@ from modules.ui import plaintext_to_html
import modules.scripts


def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):
def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args, to_scale=False, scale_by=1.0):
    processing.fix_seed(p)

    images = shared.listfiles(input_dir)
@@ -49,14 +50,31 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):
            continue
        # Use the EXIF orientation of photos taken by smartphones.
        img = ImageOps.exif_transpose(img)

        if to_scale:
            p.width = int(img.width * scale_by)
            p.height = int(img.height * scale_by)

        p.init_images = [img] * p.batch_size

        image_path = Path(image)
        if is_inpaint_batch:
            # try to find corresponding mask for an image using simple filename matching
            mask_image_path = os.path.join(inpaint_mask_dir, os.path.basename(image))
            # if not found use first one ("same mask for all images" use-case)
            if mask_image_path not in inpaint_masks:
            if len(inpaint_masks) == 1:
                mask_image_path = inpaint_masks[0]
            else:
                # try to find corresponding mask for an image using simple filename matching
                mask_image_dir = Path(inpaint_mask_dir)
                masks_found = list(mask_image_dir.glob(f"{image_path.stem}.*"))

                if len(masks_found) == 0:
                    print(f"Warning: mask is not found for {image_path} in {mask_image_dir}. Skipping it.")
                    continue

                # it should contain only 1 matching mask
                # otherwise user has many masks with the same name but different extensions
                mask_image_path = masks_found[0]

            mask_image = Image.open(mask_image_path)
            p.image_mask = mask_image

@@ -65,7 +83,7 @@ def process_batch(p, input_dir, output_dir, inpaint_mask_dir, args):
            proc = process_images(p)

        for n, processed_image in enumerate(proc.images):
            filename = os.path.basename(image)
            filename = image_path.name

            if n > 0:
                left, right = os.path.splitext(filename)
@@ -115,7 +133,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
    if image is not None:
        image = ImageOps.exif_transpose(image)

    if selected_scale_tab == 1:
    if selected_scale_tab == 1 and not is_batch:
        assert image, "Can't scale by because no image is selected"

        width = int(image.width * scale_by)
@@ -170,7 +188,7 @@ def img2img(id_task: str, mode: int, prompt: str, negative_prompt: str, prompt_s
    if is_batch:
        assert not shared.cmd_opts.hide_ui_dir_config, "Launched with --hide-ui-dir-config, batch img2img disabled"

        process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir, args)
        process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, img2img_batch_inpaint_mask_dir, args, to_scale=selected_scale_tab == 1, scale_by=scale_by)

        processed = Processed(p, [], p.seed, "")
    else: