def __call__(self) -> Generator[PipeImage, PipeImage, None]: while True: image = yield if self.pipeline.verbosity >= 2: print(f" {self}") if image.mode == "RGBA": rgba = Image.open(image.last) rgb_outfile = validate_output_path( self.pipeline.get_outfile(image, "RGB") ) a_outfile = validate_output_path(self.pipeline.get_outfile(image, "A")) if not isfile(rgb_outfile): if self.pipeline.verbosity >= 3: print(f" saving RGB to '{rgb_outfile}'") Image.fromarray(np.array(rgba)[:, :, :3]).save(rgb_outfile) image.log(self.name, rgb_outfile) if self.downstream_stages_for_rgb is not None: for pipe in self.downstream_stages_for_rgb: self.pipeline.stages[pipe].send(image) if not isfile(a_outfile): if self.pipeline.verbosity >= 3: print(f" saving alpha to '{a_outfile}'") Image.fromarray(np.array(rgba)[:, :, 3]).save(a_outfile) image.log(self.name, a_outfile) if self.downstream_stages_for_a is not None: for pipe in self.downstream_stages_for_a: self.pipeline.stages[pipe].send(image) else: raise ValueError()
def __call__(self) -> Generator[PipeImage, PipeImage, None]: while True: image = yield rgb_infile = image.last image = yield a_infile = image.last stages = get_name(image.last).split("_") if "A" in stages: rstrip = "_".join(stages[stages.index("A"):]) else: rstrip = "_".join(stages[stages.index("RGB"):]) rgb_datum = np.array(Image.open(rgb_infile)) a_datum = np.array(Image.open(a_infile).convert("L")) outfile = validate_output_path( self.pipeline.get_outfile(image, "merge-RGBA", rstrip=rstrip)) if not isfile(outfile): if self.pipeline.verbosity >= 2: print(f"{self} merging: {image.name}") rgba_datum = np.zeros( (rgb_datum.shape[0], rgb_datum.shape[1], 4), np.uint8) rgba_datum[:, :, :3] = rgb_datum rgba_datum[:, :, 3] = a_datum rgba_image = Image.fromarray(rgba_datum) rgba_image.save(outfile) image.log(self.name, outfile) if self.downstream_stages is not None: for pipe in self.downstream_stages: self.pipeline.stages[pipe].send(image)
def __init__( self, pipeline: Pipeline, directory: str, downstream_stages: Optional[Union[List[str], str]] = None, **kwargs: Any, ) -> None: # Prepare attributes self.pipeline = pipeline self.directory = validate_output_path(directory, file_ok=False, directory_ok=True) if isinstance(downstream_stages, str): downstream_stages = [downstream_stages] self.downstream_stages = downstream_stages self.infiles = [ validate_input_path(f, default_directory=self.directory) for f in listdir(self.directory) if f != ".DS_Store" ] self.infiles.sort(key=self.sort) # Prepare name and description self.name = self.__class__.__name__.lower() desc = f"source {self.__class__.__name__} ({self.directory})" if self.downstream_stages is not None: if len(self.downstream_stages) >= 2: for stage in self.downstream_stages[:-1]: desc += f"\n ├─ {stage}" desc += f"\n └─ {self.downstream_stages[-1]}" self.desc = desc
def process_file_in_pipeline(self, image: PipeImage) -> None: infile = image.last outfile = validate_output_path(self.pipeline.get_outfile(image, self.suffix)) if not isfile(outfile): self.process_file( infile, outfile, self.pipeline.verbosity, scale=self.scale, ) image.log(self.name, outfile)
def process_file_from_cl(cls, infile: str, outfile: str, **kwargs): infile = validate_input_path(infile) outfile = validate_output_path(outfile) model_infile = validate_input_path(kwargs.get("model_infile")) device = kwargs.get("device") upscaler = ESRGANProcessor.RRDBNetUpscaler(model_infile, torch.device(device)) cls.process_file(infile, outfile, upscaler=upscaler, **kwargs)
def __init__( self, wip_directory: str, source: Dict[str, Dict[str, Any]], stages: Dict[str, Dict[str, Any]], verbosity: int = 1, ) -> None: # Store configuration self.wip_directory = validate_output_path(wip_directory, file_ok=False, directory_ok=True) self.verbosity = validate_int(verbosity, min_value=0) # Load configuration sources_module = import_module("pipescaler.sources") stage_modules = [ import_module(f"pipescaler.{package}") for package in ["mergers", "processors", "sorters", "splitters"] ] # Configure source source_cls_name = list(source.keys())[0] source_args = list(source.values())[0] source_cls = getattr(sources_module, source_cls_name) self.source = source_cls(pipeline=self, **source_args) print(repr(self.source)) # Configure stages self.stages: Dict[str, Stage] = {} for stage_name, stage_conf in stages.items(): if "module" in stage_conf: module_path = validate_input_path(stage_conf.pop("module")) else: module_path = None stage_cls_name = list(stage_conf.keys())[0] stage_args = list(stage_conf.values())[0] if stage_args is None: stage_args = {} if module_path is not None: spec = spec_from_file_location( splitext(basename(module_path))[0], module_path) module = module_from_spec(spec) spec.loader.exec_module(module) stage_cls = getattr(module, stage_cls_name) else: stage_cls = None for module in stage_modules: try: stage_cls = getattr(module, stage_cls_name) except AttributeError: continue if stage_cls is None: raise AttributeError(f"Class {stage_cls_name} not found") stage = stage_cls(pipeline=self, name=stage_name, **stage_args) print(repr(stage)) self.stages[stage_name] = stage() next(self.stages[stage_name])
def process_file_in_pipeline(self, image: PipeImage) -> None: infile = validate_input_path(image.last) outfile = validate_output_path( f"{self.output_directory}/{image.name}.{get_ext(image.last)}") if not isfile(outfile): self.process_file(infile, outfile, verbosity=self.pipeline.verbosity) image.log(self.name, outfile)
def process_file_from_cl(cls, infile: str, outfile: str, **kwargs: Any) -> None: infile = validate_input_path(infile) outfile = validate_output_path(outfile) workflow = validate_input_path(kwargs.pop("workflow"), file_ok=False, directory_ok=True) cls.process_file(infile, outfile, workflow=workflow, **kwargs)
def __call__(self) -> Generator[PipeImage, PipeImage, None]: while True: image = yield if self.pipeline.verbosity >= 2: print(f" splitting: {image.name}") rgb = Image.open(image.last) r_outfile = validate_output_path( self.pipeline.get_outfile(image, "R")) g_outfile = validate_output_path( self.pipeline.get_outfile(image, "G")) b_outfile = validate_output_path( self.pipeline.get_outfile(image, "B")) if not isfile(r_outfile): if self.pipeline.verbosity >= 3: print(f" saving red to '{r_outfile}'") Image.fromarray(np.array(rgb)[:, :, 0]).save(r_outfile) image.log(self.name, r_outfile) if self.downstream_stages_for_rgb is not None: for pipe in self.downstream_stages_for_rgb: self.pipeline.stages[pipe].send(image) if not isfile(g_outfile): if self.pipeline.verbosity >= 3: print(f" saving green to '{g_outfile}'") Image.fromarray(np.array(rgb)[:, :, 1]).save(g_outfile) image.log(self.name, g_outfile) if self.downstream_stages_for_rgb is not None: for pipe in self.downstream_stages_for_rgb: self.pipeline.stages[pipe].send(image) if not isfile(b_outfile): if self.pipeline.verbosity >= 3: print(f" saving blue to '{b_outfile}'") Image.fromarray(np.array(rgb)[:, :, 2]).save(b_outfile) image.log(self.name, b_outfile) if self.downstream_stages_for_rgb is not None: for pipe in self.downstream_stages_for_rgb: self.pipeline.stages[pipe].send(image)
def process_file_in_pipeline(self, image: PipeImage) -> None: if image.name in self.infiles: infile = self.infiles[image.name] outfile = validate_output_path( self.pipeline.get_outfile(image, self.suffix) ) if not isfile(outfile): self.process_file(infile, outfile, self.pipeline.verbosity) image.log(self.name, outfile) else: raise FileNotFoundError( f"{self} did not file matching '{image.name}' in '{self.directory}'" )
def __init__( self, infiles: List[str], outfile: str, labels: Optional[List[str]] = None, show_size: bool = False, duration: Optional[int] = 500, **kwargs: Any, ) -> None: super().__init__(**kwargs) self.infiles = list(map(validate_input_path, infiles)) self.outfile = validate_output_path(outfile) self.labels = labels if self.labels is not None and len(self.labels) != len(self.infiles): raise ValueError self.show_size = show_size self.duration = duration self.apngasm_executable = validate_executable("apngasm")
def __call__(self) -> Generator[PipeImage, PipeImage, None]: while True: image = yield if self.pipeline.verbosity >= 2: print(f" {self}") if image.mode == "RGBA": if self.drop_alpha_threshold is not None and np.all( np.array(Image.open(image.last))[:, :, 3] >= self.drop_alpha_threshold ): outfile = validate_output_path( self.pipeline.get_outfile(image, "RGB") ) if not isfile(outfile): if self.pipeline.verbosity >= 2: print(f" RGBA, but dropping A and treating as RGB") rgba_image = Image.open(image.last) rgb_image = Image.fromarray(np.zeros((rgba_image.size[0], rgba_image.size[1], 3), np.uint8)) rgb_image.paste(rgba_image) rgb_image.save(outfile) image.log(self.name, outfile) if self.downstream_stages_for_rgb is not None: for stage in self.downstream_stages_for_rgb: self.pipeline.stages[stage].send(image) else: if self.pipeline.verbosity >= 2: print(f" RGBA") if self.downstream_stages_for_rgba is not None: for stage in self.downstream_stages_for_rgba: self.pipeline.stages[stage].send(image) elif image.mode == "RGB": if self.pipeline.verbosity >= 2: print(f" RGB") if self.downstream_stages_for_rgb is not None: for stage in self.downstream_stages_for_rgb: self.pipeline.stages[stage].send(image) elif image.mode == "L": if self.pipeline.verbosity >= 2: print(f" L") if self.downstream_stages_for_l is not None: for stage in self.downstream_stages_for_l: self.pipeline.stages[stage].send(image)
def process_file_in_pipeline(self, image: PipeImage) -> None: if not any(win32_ver()): raise UnsupportedPlatformError( "TexconvProcessor may only be used on Windows") if not which("texconv.exe"): raise ExecutableNotFoundError( "texcov.exe executable not found in PATH") infile = image.last outfile = validate_output_path( self.pipeline.get_outfile(image, self.suffix, extension="dds")) if not isfile(outfile): self.process_file( infile, outfile, self.pipeline.verbosity, sepalpha=self.sepalpha, filetype=self.filetype, format=self.format, ) image.log(self.name, outfile)
def __call__(self) -> Generator[PipeImage, PipeImage, None]: while True: image = yield r_infile = image.last image = yield g_infile = image.last image = yield b_infile = image.last stages = get_name(image.last).split("_") rstrip = "_" + "_".join(stages[stages.index("B"):]) outfile = validate_output_path( self.pipeline.get_outfile(image, "merge-RGB", rstrip=rstrip) ) if not isfile(outfile): if self.pipeline.verbosity >= 2: print(f" merging: {image.name}") r_datum = np.array(Image.open(r_infile).convert("L"), np.float) - 128 g_datum = np.array(Image.open(g_infile).convert("L"), np.float) - 128 b_datum = np.array(Image.open(b_infile).convert("L"), np.float) - 128 b_datum[b_datum < 0] = 0 mag = np.sqrt(r_datum ** 2 + g_datum ** 2 + b_datum ** 2) r_datum = (((r_datum / mag) * 128) + 128).astype(np.uint8) g_datum = (((g_datum / mag) * 128) + 128).astype(np.uint8) b_datum = (((b_datum / mag) * 128) + 128).astype(np.uint8) b_datum[b_datum == 0] = 255 rgb_datum = np.zeros((r_datum.shape[0], r_datum.shape[1], 3), np.uint8) rgb_datum[:, :, 0] = r_datum rgb_datum[:, :, 1] = g_datum rgb_datum[:, :, 2] = b_datum rgb_image = Image.fromarray(rgb_datum) rgb_image.save(outfile) image.log(self.name, outfile) if self.downstream_stages is not None: for pipe in self.downstream_stages: self.pipeline.stages[pipe].send(image)
def process_file_from_cl(cls, infile: str, outfile: str, **kwargs: Any) -> None: infile = validate_input_path(infile) outfile = validate_output_path(outfile) cls.process_file(infile, outfile, **kwargs)
def output_directory(self, value: str) -> None: self._output_directory = validate_output_path(value, file_ok=False, directory_ok=True)