          cv2.imwrite(output_file, image)  # pylint: disable=no-member
  
  
  class Faces(MediaLoader):
      """ Object to hold the faces that are to be swapped out """
  
      def process_folder(self):
          """ Iterate through the faces folder pulling out various information """
          logger.info("Loading file list from %s", self.folder)
  
 
</s> remove         """ Iterate through the faces folder pulling out various information """
 </s> add         """ Iterate through the faces folder pulling out various information for each face.

        Yields
        ------
        dict
            A dictionary for each face found containing the keys returned from
            :class:`lib.image.read_image_meta_batch`
        """ </s> remove         cv2.imwrite(output_file, image)  # pylint: disable=no-member
 </s> add         if metadata:
            encoded_image = cv2.imencode(".png", image)[1]
            encoded_image = png_write_meta(encoded_image.tobytes(), metadata)
            with open(output_file, "wb") as out_file:
                out_file.write(encoded_image)
        else:
            cv2.imwrite(output_file, image)  # pylint: disable=no-member </s> remove         filelist = [os.path.join(self.folder, face)
                    for face in os.listdir(self.folder)
                    if self.valid_extension(face)]
        for fullpath, face_hash in tqdm(read_image_hash_batch(filelist),
                                        total=len(filelist),
                                        desc="Reading Face Hashes"):
            filename = os.path.basename(fullpath)
            face_name, extension = os.path.splitext(filename)
            retval = {"face_fullname": filename,
                      "face_name": face_name,
                      "face_extension": extension,
                      "face_hash": face_hash}
            logger.trace(retval)
 </s> add         if self._alignments is not None:  # Legacy updating
            filelist = [os.path.join(self.folder, face)
                        for face in os.listdir(self.folder)
                        if self.valid_extension(face)]
        else:
            filelist = [os.path.join(self.folder, face)
                        for face in os.listdir(self.folder)
                        if os.path.splitext(face)[-1] == ".png"]

        log_once = False
        for fullpath, metadata in tqdm(read_image_meta_batch(filelist),
                                       total=len(filelist),
                                       desc="Reading Face Data"):

            if "itxt" not in metadata or "source" not in metadata["itxt"]:
                if self._alignments is None:  # Can't update legacy
                    raise FaceswapError(
                        f"The folder '{self.folder}' contains images that do not include Faceswap "
                        "metadata.\nAll images in the provided folder should contain faces "
                        "generated from Faceswap's extraction process.\nPlease double check the "
                        "source and try again.")

                if not log_once:
                    logger.warning("Legacy faces discovered. These faces will be updated")
                    log_once = True
                data = update_legacy_png_header(fullpath, self._alignments)
                if not data:
                    raise FaceswapError(
                        "Some of the faces being passed in from '{}' could not be matched to the "
                        "alignments file '{}'\nPlease double check your sources and try "
                        "again.".format(self.folder, self._alignments.file))
                retval = data["source"]
            else:
                retval = metadata["itxt"]["source"]

            retval["current_filename"] = os.path.basename(fullpath) </s> remove         output_file = os.path.splitext(output_file)[0]+'.png'
 </s> add         output_file = os.path.splitext(output_file)[0] + ".png" </s> remove         """ For each frame save out the faces and update the face hash back to alignments
 </s> add         """ For each frame save out the faces
    """ Object to load Extracted Faces from a folder.

    Parameters
    ----------
    folder: str
        The folder to load faces from
    alignments: :class:`lib.align.Alignments`, optional
        The alignments object that contains the faces. Used to update legacy hash based faces
        for <v2.1 alignments to png header based version. Pass in ``None`` to not update legacy
        faces (raises error instead). Default: ``None``
    """
    def __init__(self, folder, alignments=None):
        self._alignments = alignments
        super().__init__(folder)
          cv2.imwrite(output_file, image)  # pylint: disable=no-member
  
  
  class Faces(MediaLoader):
    """ Object to load Extracted Faces from a folder.

    Parameters
    ----------
    folder: str
        The folder to load faces from
    alignments: :class:`lib.align.Alignments`, optional
        The alignments object that contains the faces. Used to update legacy hash based faces
        for <v2.1 alignments to png header based version. Pass in ``None`` to not update legacy
        faces (raises error instead). Default: ``None``
    """
    def __init__(self, folder, alignments=None):
        self._alignments = alignments
        super().__init__(folder)
  
      def process_folder(self):
          """ Iterate through the faces folder pulling out various information """
          logger.info("Loading file list from %s", self.folder)
  
keep keep keep keep replace keep keep keep keep keep
 Update extracted faces to use PNG EXIF data (#1123)

Documentation
  - Update Usage.md, align.rst and image.rst
lib.image.py
  - read_image - Remove hash return, add metadata return
  - Remove read_image_hash functions
  - Add read_image_meta functios
  - Replace encode_image_with_hash with encode_image (to store metadata)
  - Add png meta reading and writing functions
  - Update Image Loaders/Savers to handle metadata rather than hashes
lib.training_data
  - Naming updates to remove references to hashes
lib.align.Alignments
  - Add versioning notes
  - Increment alignments version to 2.1
  - Deprecate hashing lookup functions
  - Replace filter_hashes with filter_faces
lib.align.detected_face
  - DetectedFace
    - Remove hash property
    - Add png header data serializing/deserializing functions
  - Mask
    - Add png header data serializing/deserializing functions
  - add update_legacy_png_header function to update png meta data
lib.cli.args - Deprecate alignments files for training
- plugins.train.trainer
  - Update alignments/mask code to read png header data
- scripts.convert
  - Aligned images folder - read data from png headers
- scripts.extract
  - Write png header information and no longer store hash of face
- tools.alignments
  - remove leftover-faces, merge and update-hashes jobs
  - Update jobs to use png meta data rather than hashes
- tools.manual
  - Update extract code to output png meta data and don't store hashes
  - Perform check on launch that tool is not pointing at a faces folder
tools.mask
  - Update to use png meta data
tools.sort
  - Update to use png meta data 
tools/alignments/media.py