|
@@ -662,12 +662,17 @@ def process_images_inner(p: StableDiffusionProcessing) -> Processed:
|
|
|
class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
|
|
sampler = None
|
|
|
|
|
|
- def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_upscaler: str = None, **kwargs):
|
|
|
+ def __init__(self, enable_hr: bool = False, denoising_strength: float = 0.75, firstphase_width: int = 0, firstphase_height: int = 0, hr_scale: float = 2.0, hr_upscaler: str = None, hr_second_pass_steps: int = 0, hr_resize_x: int = 0, hr_resize_y: int = 0, **kwargs):
|
|
|
super().__init__(**kwargs)
|
|
|
self.enable_hr = enable_hr
|
|
|
self.denoising_strength = denoising_strength
|
|
|
self.hr_scale = hr_scale
|
|
|
self.hr_upscaler = hr_upscaler
|
|
|
+ self.hr_second_pass_steps = hr_second_pass_steps
|
|
|
+ self.hr_resize_x = hr_resize_x
|
|
|
+ self.hr_resize_y = hr_resize_y
|
|
|
+ self.hr_upscale_to_x = hr_resize_x
|
|
|
+ self.hr_upscale_to_y = hr_resize_y
|
|
|
|
|
|
if firstphase_width != 0 or firstphase_height != 0:
|
|
|
print("firstphase_width/firstphase_height no longer supported; use hr_scale", file=sys.stderr)
|
|
@@ -675,6 +680,9 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
|
|
self.width = firstphase_width
|
|
|
self.height = firstphase_height
|
|
|
|
|
|
+ self.truncate_x = 0
|
|
|
+ self.truncate_y = 0
|
|
|
+
|
|
|
def init(self, all_prompts, all_seeds, all_subseeds):
|
|
|
if self.enable_hr:
|
|
|
if state.job_count == -1:
|
|
@@ -682,7 +690,38 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
|
|
else:
|
|
|
state.job_count = state.job_count * 2
|
|
|
|
|
|
- self.extra_generation_params["Hires upscale"] = self.hr_scale
|
|
|
+ if self.hr_resize_x == 0 and self.hr_resize_y == 0:
|
|
|
+ self.extra_generation_params["Hires upscale"] = self.hr_scale
|
|
|
+ self.hr_upscale_to_x = int(self.width * self.hr_scale)
|
|
|
+ self.hr_upscale_to_y = int(self.height * self.hr_scale)
|
|
|
+ else:
|
|
|
+ self.extra_generation_params["Hires resize"] = f"{self.hr_resize_x}x{self.hr_resize_y}"
|
|
|
+
|
|
|
+ if self.hr_resize_y == 0:
|
|
|
+ self.hr_upscale_to_x = self.hr_resize_x
|
|
|
+ self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
|
|
|
+ elif self.hr_resize_x == 0:
|
|
|
+ self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
|
|
|
+ self.hr_upscale_to_y = self.hr_resize_y
|
|
|
+ else:
|
|
|
+ target_w = self.hr_resize_x
|
|
|
+ target_h = self.hr_resize_y
|
|
|
+ src_ratio = self.width / self.height
|
|
|
+ dst_ratio = self.hr_resize_x / self.hr_resize_y
|
|
|
+
|
|
|
+ if src_ratio < dst_ratio:
|
|
|
+ self.hr_upscale_to_x = self.hr_resize_x
|
|
|
+ self.hr_upscale_to_y = self.hr_resize_x * self.height // self.width
|
|
|
+ else:
|
|
|
+ self.hr_upscale_to_x = self.hr_resize_y * self.width // self.height
|
|
|
+ self.hr_upscale_to_y = self.hr_resize_y
|
|
|
+
|
|
|
+ self.truncate_x = (self.hr_upscale_to_x - target_w) // opt_f
|
|
|
+ self.truncate_y = (self.hr_upscale_to_y - target_h) // opt_f
|
|
|
+
|
|
|
+ if self.hr_second_pass_steps:
|
|
|
+ self.extra_generation_params["Hires steps"] = self.hr_second_pass_steps
|
|
|
+
|
|
|
if self.hr_upscaler is not None:
|
|
|
self.extra_generation_params["Hires upscaler"] = self.hr_upscaler
|
|
|
|
|
@@ -699,8 +738,8 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
|
|
if not self.enable_hr:
|
|
|
return samples
|
|
|
|
|
|
- target_width = int(self.width * self.hr_scale)
|
|
|
- target_height = int(self.height * self.hr_scale)
|
|
|
+ target_width = self.hr_upscale_to_x
|
|
|
+ target_height = self.hr_upscale_to_y
|
|
|
|
|
|
def save_intermediate(image, index):
|
|
|
"""saves image before applying hires fix, if enabled in options; takes as an argument either an image or batch with latent space images"""
|
|
@@ -755,13 +794,15 @@ class StableDiffusionProcessingTxt2Img(StableDiffusionProcessing):
|
|
|
|
|
|
self.sampler = sd_samplers.create_sampler(self.sampler_name, self.sd_model)
|
|
|
|
|
|
+ samples = samples[:, :, self.truncate_y//2:samples.shape[2]-(self.truncate_y+1)//2, self.truncate_x//2:samples.shape[3]-(self.truncate_x+1)//2]
|
|
|
+
|
|
|
noise = create_random_tensors(samples.shape[1:], seeds=seeds, subseeds=subseeds, subseed_strength=subseed_strength, p=self)
|
|
|
|
|
|
# GC now before running the next img2img to prevent running out of memory
|
|
|
x = None
|
|
|
devices.torch_gc()
|
|
|
|
|
|
- samples = self.sampler.sample_img2img(self, samples, noise, conditioning, unconditional_conditioning, steps=self.steps, image_conditioning=image_conditioning)
|
|
|
+ samples = self.sampler.sample_img2img(self, samples, noise, conditioning, unconditional_conditioning, steps=self.hr_second_pass_steps or self.steps, image_conditioning=image_conditioning)
|
|
|
|
|
|
return samples
|
|
|
|