img2img.py 4.8 KB
Newer Older
1
import math
2 3 4 5
import os
import sys
import traceback

6
import numpy as np
7
from PIL import Image, ImageOps, ImageChops
8

9
from modules import devices
10 11 12 13 14 15
from modules.processing import Processed, StableDiffusionProcessingImg2Img, process_images
from modules.shared import opts, state
import modules.shared as shared
import modules.processing as processing
from modules.ui import plaintext_to_html
import modules.images as images
A
AUTOMATIC 已提交
16
import modules.scripts
17

18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

def process_batch(p, input_dir, output_dir, args):
    processing.fix_seed(p)

    images = [file for file in [os.path.join(input_dir, x) for x in os.listdir(input_dir)] if os.path.isfile(file)]

    print(f"Will process {len(images)} images, creating {p.n_iter * p.batch_size} new images for each.")

    p.do_not_save_grid = True
    p.do_not_save_samples = True

    state.job_count = len(images) * p.n_iter

    for i, image in enumerate(images):
        state.job = f"{i+1} out of {len(images)}"

        if state.interrupted:
            break

        img = Image.open(image)
        p.init_images = [img] * p.batch_size

        proc = modules.scripts.scripts_img2img.run(p, *args)
        if proc is None:
            proc = process_images(p)

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

            if n > 0:
                left, right = os.path.splitext(filename)
                filename = f"{left}-{n}{right}"

            processed_image.save(os.path.join(output_dir, filename))


def img2img(mode: int, prompt: str, negative_prompt: str, prompt_style: str, prompt_style2: str, init_img, init_img_with_mask, init_img_inpaint, init_mask_inpaint, mask_mode, steps: int, sampler_index: int, mask_blur: int, inpainting_fill: int, restore_faces: bool, tiling: bool, n_iter: int, batch_size: int, cfg_scale: float, denoising_strength: float, seed: int, subseed: int, subseed_strength: float, seed_resize_from_h: int, seed_resize_from_w: int, seed_enable_extras: bool, height: int, width: int, resize_mode: int, inpaint_full_res: bool, inpaint_full_res_padding: int, inpainting_mask_invert: int, img2img_batch_input_dir: str, img2img_batch_output_dir: str, *args):
55
    is_inpaint = mode == 1
56
    is_batch = mode == 2
57 58

    if is_inpaint:
59 60 61 62 63 64 65
        if mask_mode == 0:
            image = init_img_with_mask['image']
            mask = init_img_with_mask['mask']
            alpha_mask = ImageOps.invert(image.split()[-1]).convert('L').point(lambda x: 255 if x > 0 else 0, mode='1')
            mask = ImageChops.lighter(alpha_mask, mask.convert('L')).convert('L')
            image = image.convert('RGB')
        else:
66 67
            image = init_img_inpaint
            mask = init_mask_inpaint
68 69 70 71 72 73 74 75 76 77 78
    else:
        image = init_img
        mask = None

    assert 0. <= denoising_strength <= 1., 'can only work with strength in [0.0, 1.0]'

    p = StableDiffusionProcessingImg2Img(
        sd_model=shared.sd_model,
        outpath_samples=opts.outdir_samples or opts.outdir_img2img_samples,
        outpath_grids=opts.outdir_grids or opts.outdir_img2img_grids,
        prompt=prompt,
79
        negative_prompt=negative_prompt,
A
AUTOMATIC 已提交
80
        styles=[prompt_style, prompt_style2],
81
        seed=seed,
82 83 84 85
        subseed=subseed,
        subseed_strength=subseed_strength,
        seed_resize_from_h=seed_resize_from_h,
        seed_resize_from_w=seed_resize_from_w,
86
        seed_enable_extras=seed_enable_extras,
87 88 89 90 91 92 93
        sampler_index=sampler_index,
        batch_size=batch_size,
        n_iter=n_iter,
        steps=steps,
        cfg_scale=cfg_scale,
        width=width,
        height=height,
A
AUTOMATIC 已提交
94
        restore_faces=restore_faces,
95
        tiling=tiling,
96 97 98 99 100 101 102
        init_images=[image],
        mask=mask,
        mask_blur=mask_blur,
        inpainting_fill=inpainting_fill,
        resize_mode=resize_mode,
        denoising_strength=denoising_strength,
        inpaint_full_res=inpaint_full_res,
103
        inpaint_full_res_padding=inpaint_full_res_padding,
A
AUTOMATIC 已提交
104
        inpainting_mask_invert=inpainting_mask_invert,
105
    )
106 107 108

    if shared.cmd_opts.enable_console_prompts:
        print(f"\nimg2img: {prompt}", file=shared.progress_print_out)
109

A
AUTOMATIC 已提交
110 111
    p.extra_generation_params["Mask blur"] = mask_blur

112
    if is_batch:
113 114
        assert not shared.cmd_opts.hide_ui_dir_config, "Launched with --hide-ui-dir-config, batch img2img disabled"

115
        process_batch(p, img2img_batch_input_dir, img2img_batch_output_dir, args)
116

117
        processed = Processed(p, [], p.seed, "")
118
    else:
A
AUTOMATIC 已提交
119
        processed = modules.scripts.scripts_img2img.run(p, *args)
A
AUTOMATIC 已提交
120 121 122
        if processed is None:
            processed = process_images(p)

123
    shared.total_tqdm.clear()
124

125 126 127 128
    generation_info_js = processed.js()
    if opts.samples_log_stdout:
        print(generation_info_js)

129
    return processed.images, generation_info_js, plaintext_to_html(processed.info)