コード例 #1
0
    def _extract_metadata(
        self, rpd_file: RPDFile, processing: Set[ExtractionProcessing]
    ) -> PhotoDetails:

        thumbnail = orientation = None
        try:
            orientation = rpd_file.metadata.orientation()
        except Exception:
            pass

        rpd_file.mdatatime = rpd_file.metadata.timestamp(missing=0.0)

        # Not all files have an exif preview, but some do
        # (typically CR2, ARW, PEF, RW2).
        # If they exist, they are (almost!) always 160x120

        # TODO how about thumbnail_cache_status?
        if self.write_fdo_thumbnail and rpd_file.fdo_thumbnail_256 is None:
            photo_details = self._extract_256_thumb(
                rpd_file=rpd_file, processing=processing, orientation=orientation
            )
            if photo_details.thumbnail is not None:
                return photo_details
            # if no valid preview found, fall back to the code below and make do with
            # the best we can get

        preview = rpd_file.metadata.get_small_thumbnail_or_first_indexed_preview()
        if preview:
            thumbnail = QImage.fromData(preview)
            if thumbnail.isNull():
                thumbnail = None
            else:
                if thumbnail.width() < thumbnail.height() and orientation in (
                    self.rotate_270,
                    self.rotate_90,
                ):
                    # The orientation has already been applied to the thumbnail
                    logging.debug(
                        "Already rotated: %s", rpd_file.get_current_full_file_name()
                    )
                    orientation = self.rotate_0

                if max(thumbnail.width(), thumbnail.height()) > 160:
                    logging.debug("Resizing: %s", rpd_file.get_current_full_file_name())
                    processing.add(ExtractionProcessing.resize)
                elif not rpd_file.is_jpeg():
                    processing.add(ExtractionProcessing.strip_bars_photo)

        return PhotoDetails(thumbnail, orientation)
コード例 #2
0
def preprocess_thumbnail_from_disk(
        rpd_file: RPDFile,
        processing: Set[ExtractionProcessing]) -> ExtractionTask:
    """
    Determine how to get a thumbnail from a photo or video that is not on a camera
    (although it may have directly come from there during the download process)

    Does not return the name of the file to be worked on -- that's the responsibility
    of the method calling it.

    :param rpd_file: details about file from which to get thumbnail from
    :param processing: set that holds processing tasks for the extractors to perform
    :return: extraction task required
    """

    if rpd_file.file_type == FileType.photo:
        if rpd_file.is_heif():
            if have_heif_module:
                bytes_to_read = rpd_file.size
                if rpd_file.mdatatime:
                    task = ExtractionTask.load_heif_directly
                else:
                    task = ExtractionTask.load_heif_and_exif_directly
                processing.add(ExtractionProcessing.resize)
                # For now, do not orient, as it seems pyheif or libheif does that
                # automatically processing.add(ExtractionProcessing.orient)
            else:
                # We have no way to convert the file
                task = ExtractionTask.bypass
                bytes_to_read = 0
        elif rpd_file.is_tiff():
            available = psutil.virtual_memory().available
            if rpd_file.size <= available:
                bytes_to_read = rpd_file.size
                if rpd_file.mdatatime:
                    task = ExtractionTask.load_file_directly
                else:
                    task = ExtractionTask.load_file_and_exif_directly
                processing.add(ExtractionProcessing.resize)
            else:
                # Don't try to extract a thumbnail from
                # a file that is larger than available
                # memory
                task = ExtractionTask.bypass
                bytes_to_read = 0
        else:
            if rpd_file.is_jpeg(
            ) and rpd_file.from_camera and rpd_file.is_mtp_device:
                # jpeg photos from smartphones don't have embedded thumbnails
                task = ExtractionTask.load_file_and_exif_directly
                processing.add(ExtractionProcessing.resize)
            else:
                task = ExtractionTask.load_from_exif
            processing.add(ExtractionProcessing.orient)
            bytes_to_read = cached_read.get(rpd_file.extension, 400 * 1024)

        if bytes_to_read:
            if not rpd_file.download_full_file_name:
                try:
                    with open(rpd_file.full_file_name, "rb") as photo:
                        # Bring the file into the operating system's disk cache
                        photo.read(bytes_to_read)
                except FileNotFoundError:
                    logging.error(
                        "The download file %s does not exist",
                        rpd_file.download_full_file_name,
                    )
    else:
        # video
        if rpd_file.thm_full_name is not None:
            if not rpd_file.mdatatime:
                task = ExtractionTask.load_file_directly_metadata_from_secondary
                # It's the responsibility of the calling code to assign the
                # secondary_full_file_name
            else:
                task = ExtractionTask.load_file_directly
            processing.add(ExtractionProcessing.strip_bars_video)
            processing.add(ExtractionProcessing.add_film_strip)
        else:
            if rpd_file.mdatatime:
                task = ExtractionTask.extract_from_file
            else:
                task = ExtractionTask.extract_from_file_and_load_metadata

    return task