diff --git a/README.md b/README.md index b799625..5252d2b 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ReActor 0.3.1 for StableDiffusion +# ReActor 0.3.2b for StableDiffusion ### The Fast and Simple "[roop-based](https://github.com/s0md3v/sd-webui-roop)" FaceSwap Extension with a lot of improvements and without NSFW filter (uncensored, use it on your own [responsibility](#disclaimer)) > Ex "Roop-GE" (GE - Gourieff Edition, aka "NSFW-Roop"), the extension was renamed with the version 0.3.0
diff --git a/scripts/faceswap.py b/scripts/faceswap.py index 174bb49..a274efc 100644 --- a/scripts/faceswap.py +++ b/scripts/faceswap.py @@ -6,13 +6,12 @@ from modules.processing import ( StableDiffusionProcessing, StableDiffusionProcessingImg2Img, ) -from modules.shared import cmd_opts, opts, state from PIL import Image import glob from modules.face_restoration import FaceRestoration from scripts.logger import logger -from scripts.swapper import UpscaleOptions, swap_face +from scripts.swapper import UpscaleOptions, swap_face, check_process_halt, reset_messaged from scripts.version import version_flag, app_title from scripts.console_log_patch import apply_logging_patch import os @@ -200,6 +199,10 @@ class FaceSwapScript(scripts.Script): ): self.enable = enable if self.enable: + + reset_messaged() + if check_process_halt(): + return global MODELS_PATH self.source = img @@ -228,10 +231,10 @@ class FaceSwapScript(scripts.Script): if self.source is not None: apply_logging_patch(console_logging_level) if isinstance(p, StableDiffusionProcessingImg2Img) and swap_in_source: - logger.info(f"Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index) + logger.info("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index) for i in range(len(p.init_images)): - logger.info(f"Swap in %s", i) + logger.info("Swap in %s", i) result = swap_face( self.source, p.init_images[i], @@ -243,8 +246,12 @@ class FaceSwapScript(scripts.Script): gender_target=self.gender_target, ) p.init_images[i] = result + + if shared.state.interrupted or shared.state.skipped: + return + else: - logger.error(f"Please provide a source face") + logger.error("Please provide a source face") def postprocess_batch(self, p, *args, **kwargs): if self.enable: @@ -252,8 +259,16 @@ class FaceSwapScript(scripts.Script): def postprocess_image(self, p, script_pp: scripts.PostprocessImageArgs, *args): if self.enable and self.swap_in_generated: + + current_job_number = shared.state.job_no + 1 + job_count = shared.state.job_count + if current_job_number == job_count: + reset_messaged() + if check_process_halt(): + return + if self.source is not None: - logger.info(f"Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index) + logger.info("Working: source face index %s, target face index %s", self.source_faces_index, self.faces_index) image: Image.Image = script_pp.image result = swap_face( self.source, @@ -271,4 +286,4 @@ class FaceSwapScript(scripts.Script): p.extra_generation_params.update(pp.info) script_pp.image = pp.image except: - logger.error(f"Cannot create a result image") + logger.error("Cannot create a result image") diff --git a/scripts/swapper.py b/scripts/swapper.py index 82f9830..3b467ed 100644 --- a/scripts/swapper.py +++ b/scripts/swapper.py @@ -12,6 +12,7 @@ import onnxruntime from modules.face_restoration import FaceRestoration from modules.upscaler import UpscalerData +from modules.shared import state from scripts.logger import logger import warnings @@ -50,6 +51,31 @@ def cosine_similarity(test_vec: np.ndarray, source_vecs: List[np.ndarray]) -> fl return average_cos_dist +MESSAGED_STOPPED = False +MESSAGED_SKIPPED = False + +def reset_messaged(): + global MESSAGED_STOPPED, MESSAGED_SKIPPED + if not state.interrupted: + MESSAGED_STOPPED = False + if not state.skipped: + MESSAGED_SKIPPED = False + +def check_process_halt(msgforced: bool = False): + global MESSAGED_STOPPED, MESSAGED_SKIPPED + if state.interrupted: + if not MESSAGED_STOPPED or msgforced: + logger.info("Stopped by User") + MESSAGED_STOPPED = True + return True + if state.skipped: + if not MESSAGED_SKIPPED or msgforced: + logger.info("Skipped by User") + MESSAGED_SKIPPED = True + return True + return False + + FS_MODEL = None CURRENT_FS_MODEL_PATH = None @@ -77,6 +103,10 @@ def getFaceSwapModel(model_path: str): def upscale_image(image: Image, upscale_options: UpscaleOptions): result_image = image + + if check_process_halt(msgforced=True): + return result_image + if upscale_options.do_restore_first: if upscale_options.face_restorer is not None: original_image = result_image.copy() @@ -193,6 +223,10 @@ def swap_face( gender_target: int = 0, ): result_image = target_img + + if check_process_halt(): + return result_image + if model is not None: if isinstance(source_img, str): # source_img is a base64 string @@ -214,8 +248,9 @@ def swap_face( source_face, wrong_gender = get_face_single(source_img, face_index=source_faces_index[0], gender_source=gender_source) if len(source_faces_index) != 0 and len(source_faces_index) != 1 and len(source_faces_index) != len(faces_index): - logger.info(f'Source Faces must have no entries (default=0), one entry, or same number of entries as target faces.') + logger.info("Source Faces must have no entries (default=0), one entry, or same number of entries as target faces.") elif source_face is not None: + result = target_img model_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), model) face_swapper = getFaceSwapModel(model_path) diff --git a/scripts/version.py b/scripts/version.py index 89f952c..dacacd5 100644 --- a/scripts/version.py +++ b/scripts/version.py @@ -1,5 +1,5 @@ app_title = "ReActor" -version_flag = "v0.3.1" +version_flag = "v0.3.2b" from scripts.logger import logger, get_Run, set_Run