          logger.debug("Got size: (name: '%s', width: '%s', height: '%s')",
                       name, img.width(), img.height())
          return img.width(), img.height()
  
      def resize_image(self, name: str, frame_dims: Optional[Tuple[int, int]]) -> None:
          """ Resize the training preview image based on the passed in frame size.
  
          If the canvas that holds the preview image changes, update the image size
          to fit the new canvas and refresh :attr:`previewtrain`.
  
          Parameters
 
</s> remove         Parameters
        ----------
        name: str
            The name of the training image to be resized
        frame_dims: tuple, optional
            The (width (`int`), height (`int`)) of the display panel that will display the preview.
            ``None`` if the frame dimensions are not known.
 </s> add         Should be called when terminating tasks, or when Faceswap starts up or shuts down. </s> remove         for preview in self.subnotebook.children.values():
            preview.save_preview(location)


class PreviewTrainCanvas(ttk.Frame):  # pylint: disable=too-many-ancestors
    """ Canvas to hold a training preview image

    Parameters
    ----------
    parent: :class:`tkinter.ttk.Notebook`
        The notebook that the training image canvas belongs to
    previewname: str
        The name of the preview image displayed in the canvas
    """
    def __init__(self, parent: ttk.Notebook, previewname: str) -> None:
        logger.debug("Initializing %s: (previewname: '%s')", self.__class__.__name__, previewname)
        ttk.Frame.__init__(self, parent)

        self.name = previewname
        get_images().resize_image(self.name, None)
        self.previewimage = get_images().previewtrain[self.name][1]

        self.canvas = tk.Canvas(self, bd=0, highlightthickness=0)
        self.canvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
        self.imgcanvas = self.canvas.create_image(0,
                                                  0,
                                                  image=self.previewimage,
                                                  anchor=tk.NW)
        self.bind("<Configure>", self.resize)
        logger.debug("Initialized %s:", self.__class__.__name__)

    def resize(self, event: tk.Event) -> None:
        """  Resize the image to fit the frame, maintaining aspect ratio
 </s> add  </s> remove     def __init__(self, canvas: _PreviewCanvas, taskbar: _Taskbar, image: _Image) -> None:
 </s> add     def __init__(self,
                 canvas: _PreviewCanvas,
                 taskbar: _Taskbar,
                 image: _Image,
                 is_standalone: bool) -> None: </s> remove         Parameters
        ----------
        event: :class:`tkinter.Event`
            The resize event object
        """
        logger.trace("Resizing preview image")  # type:ignore
        framesize: Optional[Tuple[int, int]] = (event.width, event.height)
        # Sometimes image is resized before frame is drawn
        framesize = None if framesize == (1, 1) else framesize
        get_images().resize_image(self.name, framesize)
        self.reload()

    def reload(self) -> None:
        """ Reload the preview image """
        logger.trace("Reloading preview image")  # type:ignore
        self.previewimage = get_images().previewtrain[self.name][1]
        self.canvas.itemconfig(self.imgcanvas, image=self.previewimage)

    def save_preview(self, location: str) -> None:
        """ Save the figure to file.

        Parameters
        ----------
        location: str
            The full path to the location to save the preview image
        """
        filename = self.name
        now = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = os.path.join(location, f"{filename}_{now}.png")
        cast("Image.Image", get_images().previewtrain[self.name][0]).save(filename)
        logger.debug("Saved preview to %s", filename)
        print(f"Saved preview to {filename}")
 </s> add         self._display.save(location) </s> remove         logger.trace("Displaying preview")  # type:ignore
        sortednames = sorted(list(get_images().previewtrain.keys()))
        existing = self.subnotebook_get_titles_ids()
        should_update = self.update_preview.get()

        for name in sortednames:
            if name not in existing:
                self.add_child(name)
            elif should_update:
                tab_id = existing[name]
                self.update_child(tab_id, name)

        if should_update:
            self.update_preview.set(False)

    def add_child(self, name: str) -> None:
        """ Add the preview canvas child

        Parameters
        ----------
        name: str
            The name of the notebook tab to add
        """
        logger.debug("Adding child")
        preview = PreviewTrainCanvas(self.subnotebook, name)
        preview = self.subnotebook_add_page(name, widget=preview)
        Tooltip(preview, text=self.helptext, wrap_length=200)
        self.vars["modified"].set(get_images().previewtrain[name][2])

    def update_child(self, tab_id: int, name: str) -> None:
        """ Update the preview canvas
 </s> add         if self.subnotebook.children:
            return
        """
        size = get_config().user_config_dict.get("icon_size", 16)
        size = int(round(size * get_config().scaling_factor))
        icons: Dict[str, ImageTk.PhotoImage] = {}
        pathicons = os.path.join(PATHCACHE, "icons")
        for fname in os.listdir(pathicons):
            name, ext = os.path.splitext(fname)
            if ext != ".png":
                continue
            img = Image.open(os.path.join(pathicons, fname))
            img = ImageTk.PhotoImage(img.resize((size, size), resample=Image.HAMMING))
            icons[name] = img
        logger.debug(icons)
        return icons
          logger.debug("Got size: (name: '%s', width: '%s', height: '%s')",
                       name, img.width(), img.height())
          return img.width(), img.height()
  
        """
        size = get_config().user_config_dict.get("icon_size", 16)
        size = int(round(size * get_config().scaling_factor))
        icons: Dict[str, ImageTk.PhotoImage] = {}
        pathicons = os.path.join(PATHCACHE, "icons")
        for fname in os.listdir(pathicons):
            name, ext = os.path.splitext(fname)
            if ext != ".png":
                continue
            img = Image.open(os.path.join(pathicons, fname))
            img = ImageTk.PhotoImage(img.resize((size, size), resample=Image.HAMMING))
            icons[name] = img
        logger.debug(icons)
        return icons
        """
        size = get_config().user_config_dict.get("icon_size", 16)
        size = int(round(size * get_config().scaling_factor))
        icons: Dict[str, ImageTk.PhotoImage] = {}
        pathicons = os.path.join(PATHCACHE, "icons")
        for fname in os.listdir(pathicons):
            name, ext = os.path.splitext(fname)
            if ext != ".png":
                continue
            img = Image.open(os.path.join(pathicons, fname))
            img = ImageTk.PhotoImage(img.resize((size, size), resample=Image.HAMMING))
            icons[name] = img
        logger.debug(icons)
        return icons
  
          If the canvas that holds the preview image changes, update the image size
          to fit the new canvas and refresh :attr:`previewtrain`.
  
          Parameters
keep keep keep keep replace replace keep keep keep keep keep
 GUI - Preview updates
  - Training preview. Embed preview pop-out window
  - Bugfix - convert/extract previews 
lib/gui/utils/image.py