stable-diffusion-webui
147 строк · 4.0 Кб
1import os2from abc import abstractmethod3
4import PIL5from PIL import Image6
7import modules.shared8from modules import modelloader, shared9
10LANCZOS = (Image.Resampling.LANCZOS if hasattr(Image, 'Resampling') else Image.LANCZOS)11NEAREST = (Image.Resampling.NEAREST if hasattr(Image, 'Resampling') else Image.NEAREST)12
13
14class Upscaler:15name = None16model_path = None17model_name = None18model_url = None19enable = True20filter = None21model = None22user_path = None23scalers: []24tile = True25
26def __init__(self, create_dirs=False):27self.mod_pad_h = None28self.tile_size = modules.shared.opts.ESRGAN_tile29self.tile_pad = modules.shared.opts.ESRGAN_tile_overlap30self.device = modules.shared.device31self.img = None32self.output = None33self.scale = 134self.half = not modules.shared.cmd_opts.no_half35self.pre_pad = 036self.mod_scale = None37self.model_download_path = None38
39if self.model_path is None and self.name:40self.model_path = os.path.join(shared.models_path, self.name)41if self.model_path and create_dirs:42os.makedirs(self.model_path, exist_ok=True)43
44try:45import cv2 # noqa: F40146self.can_tile = True47except Exception:48pass49
50@abstractmethod51def do_upscale(self, img: PIL.Image, selected_model: str):52return img53
54def upscale(self, img: PIL.Image, scale, selected_model: str = None):55self.scale = scale56dest_w = int((img.width * scale) // 8 * 8)57dest_h = int((img.height * scale) // 8 * 8)58
59for _ in range(3):60if img.width >= dest_w and img.height >= dest_h:61break62
63shape = (img.width, img.height)64
65img = self.do_upscale(img, selected_model)66
67if shape == (img.width, img.height):68break69
70if img.width != dest_w or img.height != dest_h:71img = img.resize((int(dest_w), int(dest_h)), resample=LANCZOS)72
73return img74
75@abstractmethod76def load_model(self, path: str):77pass78
79def find_models(self, ext_filter=None) -> list:80return modelloader.load_models(model_path=self.model_path, model_url=self.model_url, command_path=self.user_path, ext_filter=ext_filter)81
82def update_status(self, prompt):83print(f"\nextras: {prompt}", file=shared.progress_print_out)84
85
86class UpscalerData:87name = None88data_path = None89scale: int = 490scaler: Upscaler = None91model: None92
93def __init__(self, name: str, path: str, upscaler: Upscaler = None, scale: int = 4, model=None):94self.name = name95self.data_path = path96self.local_data_path = path97self.scaler = upscaler98self.scale = scale99self.model = model100
101def __repr__(self):102return f"<UpscalerData name={self.name} path={self.data_path} scale={self.scale}>"103
104
105class UpscalerNone(Upscaler):106name = "None"107scalers = []108
109def load_model(self, path):110pass111
112def do_upscale(self, img, selected_model=None):113return img114
115def __init__(self, dirname=None):116super().__init__(False)117self.scalers = [UpscalerData("None", None, self)]118
119
120class UpscalerLanczos(Upscaler):121scalers = []122
123def do_upscale(self, img, selected_model=None):124return img.resize((int(img.width * self.scale), int(img.height * self.scale)), resample=LANCZOS)125
126def load_model(self, _):127pass128
129def __init__(self, dirname=None):130super().__init__(False)131self.name = "Lanczos"132self.scalers = [UpscalerData("Lanczos", None, self)]133
134
135class UpscalerNearest(Upscaler):136scalers = []137
138def do_upscale(self, img, selected_model=None):139return img.resize((int(img.width * self.scale), int(img.height * self.scale)), resample=NEAREST)140
141def load_model(self, _):142pass143
144def __init__(self, dirname=None):145super().__init__(False)146self.name = "Nearest"147self.scalers = [UpscalerData("Nearest", None, self)]148