Ejemplo n.º 1
0
def get_created_date(im: Image) -> dt.datetime:
    if im._getexif() and 36867 in im._getexif():
        created_date = im._getexif()[36867]
    else:
        created_date = '1990:1:1 0:0:0'
    created_date = created_date.strip()

    photo_date = dt.datetime(1990, 1, 1)
    try:
        photo_date = dt.datetime.strptime(created_date, '%Y:%m:%d %H:%M:%S')
    except Exception as ex:
        logging.debug(ex)

    return photo_date
Ejemplo n.º 2
0
def get_exif_orientation(image: Image) -> int:
    """Returns exif orientation (1-8) or 0 if no exif data"""
    if hasattr(image, "_getexif"):
        exif = image._getexif()
        if exif is not None and EXIF_ORIENTATION in exif.keys():
            return exif[EXIF_ORIENTATION]
    return 0
Ejemplo n.º 3
0
def _check_rotation_exif(image: Image) -> Image:
    """
    Checks the rotational exif data on a given image and rotates it
    accordingly.
    :param image:
    :return:
        Rotated image.
    :rtype:
        PIL.Image
    """
    for orientation in ExifTags.TAGS.keys():
        if ExifTags.TAGS[orientation] == 'Orientation':
            try:
                exif = dict(image._getexif().items())
                val = exif[orientation]
            except (AttributeError, KeyError):
                return image

            if val == 3:
                image = image.rotate(180, expand=True)
            elif val == 6:
                image = image.rotate(270, expand=True)
            elif val == 8:
                image = image.rotate(90, expand=True)
            return image
    return image
Ejemplo n.º 4
0
def image_transpose_exif(im: Image):
    """
    Apply Image.transpose to ensure 0th row of pixels is at the visual
    top of the image, and 0th column is the visual left-hand side.
    Return the original image if unable to determine the orientation.

    As per CIPA DC-008-2012, the orientation field contains an integer,
    1 through 8. Other values are reserved.

    Parameters
    ----------
    im: PIL.Image
       The image to be rotated.
    """

    exif_orientation_tag = 0x0112
    exif_transpose_sequences = [  # Val  0th row  0th col
        [],  #  0    (reserved)
        [],  #  1   top      left
        [Image.FLIP_LEFT_RIGHT],  #  2   top      right
        [Image.ROTATE_180],  #  3   bottom   right
        [Image.FLIP_TOP_BOTTOM],  #  4   bottom   left
        [Image.FLIP_LEFT_RIGHT, Image.ROTATE_90],  #  5   left     top
        [Image.ROTATE_270],  #  6   right    top
        [Image.FLIP_TOP_BOTTOM, Image.ROTATE_90],  #  7   right    bottom
        [Image.ROTATE_90],  #  8   left     bottom
    ]

    try:
        seq = exif_transpose_sequences[im._getexif()[exif_orientation_tag]  # pylint: disable=protected-access
                                       ]
    except Exception:
        return im
    else:
        return functools.reduce(type(im).transpose, seq, im)
Ejemplo n.º 5
0
def check_metadata(image_file: Image):
    """
    For decreasing image size better to delete unnecessary metadata
    :param image_file: JpegImageFile, WebPImageFile
    """
    exif = image_file._getexif()
    assert_that(exif, equal_to(None),
                'EXIF (metadata) must be empty for a smaller image file size')
Ejemplo n.º 6
0
def get_exif(img: Image) -> tp.Dict[str, str]:
    info = img._getexif()
    exif_obj = {}
    if info is not None:
        for tag, value in info.items():
            decoded = ExifTags.TAGS.get(tag, tag)
            exif_obj[decoded] = value

    return exif_obj
Ejemplo n.º 7
0
def rotate_image(image: Image) -> Image:
    ALLOCATION={3: 180,
                6: -90,
                8: 90}        #{orientation value : rotation angle}
    exif=image._getexif()
    # print(f"exif={exif}")
    if exif != None and 274 in exif:
        if exif[274] in ALLOCATION:
            return image.rotate(ALLOCATION[exif[274]], expand=True)
        else: return image
    else: return image
Ejemplo n.º 8
0
def rotate_img(img: Image) -> Image:
    try:
        #exif情報取得
        exifinfo = img._getexif()
        #exif情報からOrientationの取得
        orientation = exifinfo.get(0x112, 1)
        #画像を回転
        img = rotateImage(img, orientation)
    except:
        pass
    return img
Ejemplo n.º 9
0
def generate_exif_dict(image: Image, close: bool = True) -> Dict:
    """
    Generate a dictionary of dictionaries.

    The outer dictionary keys are the names
    of individual items, eg Make, Model etc.

    The outer dictionary values are themselves
    dictionaries with the following keys:

        tag: the numeric code for the item names
        raw: the data as stored in the image, often
        in a non-human-readable format
        processed: the raw data if it is human-readable,
        or a processed version if not.
    """

    try:

        exif_data_PIL = image._getexif()

        exif_data = {}

        for k, v in PIL.ExifTags.TAGS.items():

            try:
                if k in exif_data_PIL:
                    value = exif_data_PIL[k]
                else:
                    value = None
            except TypeError:
                raise Exception(f"{image.filename}: invalid exif_data.")

            if len(str(value)) > 64:
                value = str(value)[:65] + "..."

            exif_data[v] = {
                "tag": k,
                "raw": value,
                "processed": value,
            }

        if close:
            image.close()

        exif_data = _process_exif_dict(exif_data)

        return exif_data

    except IOError as ioe:

        raise
Ejemplo n.º 10
0
def _get_creation_time(path: Path, img: Image) -> Optional[datetime]:
    if hasattr(img, '_getexif'):
        exif = img._getexif()
        if exif and _EXIF.CREATION_DATE in exif:
            creation_date_str = exif[_EXIF.CREATION_DATE]
            try:
                return datetime.strptime(creation_date_str,
                                         '%Y:%m:%d %H:%M:%S')
            except ValueError:
                logger.error('Error parsing creation date "{}" of image {}'
                             .format(creation_date_str, path), exc_info=True)
        return None
    return None
Ejemplo n.º 11
0
def get_metadata(image: Image) -> dict:
    exif_tags = TAGS.items()

    exif = image._getexif()

    metadata = {}

    if not exif:
        return metadata

    for k, v in exif_tags:
        if k in exif:
            metadata[v] = str(exif[k])
    return metadata
Ejemplo n.º 12
0
def exif_rotate(image: Image) -> Image:
    if hasattr(image, '_getexif') is False:
        return image
    exif_dict = dict(image._getexif().items())
    orientation = exif_dict.get(name_to_tag_num['Orientation'])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Ejemplo n.º 13
0
    def _rotate_exif_orientation(self, img: Image) -> Image:
        """Rotate the image according to metadata in the payload.

        Some cameras do not rotate the image, they just add orientation
        metadata to the file, so we rotate it here.
        """
        if not hasattr(img, '_getexif'):
            return img  # PIL.PngImagePlugin.PngImageFile apparently lacks EXIF
        tags = img._getexif()
        if tags is None:
            return img
        orientation = tags.get(self.EXIF_TAGS['Orientation'])
        if orientation is None:
            return img
        degrees = self.EXIF_ROTATION_FIX.get(orientation)
        return img.rotate(degrees) if degrees else img
Ejemplo n.º 14
0
def get_exif(image: Image):
    _exif = {}
    info = image._getexif()
    for tag, value in info.items():
        decoded = ExifTags.TAGS.get(tag, tag)
        _exif[decoded] = value

    return {
        'ISOSpeedRatings': get_int(_exif, 'ISOSpeedRatings'),
        'FocalLength': get_string(_exif, 'FocalLengthIn35mmFilm') if 'FocalLengthIn35mmFilm' in _exif
        else parse_tuple(_exif, 'FocalLength'),
        'FNumber': parse_tuple(_exif, 'FNumber'),
        'ExposureTime': parse_tuple(_exif, 'ExposureTime', True),
        'Make': get_string(_exif, 'Make'),
        'Model': get_string(_exif, 'Model'),
        'ExposureProgram': get_value(_exif, 'ExposureProgram', exposure_programs)
    }
Ejemplo n.º 15
0
def rotate_image(im: Image) -> Image:
    try:
        orientation = -1
        for orientation in ExifTags.TAGS.keys():
            if ExifTags.TAGS[orientation] == 'Orientation': break
        exif = dict(im._getexif().items())

        if orientation in exif and exif[orientation] == 3:
            im = im.rotate(180, expand=True)
        elif orientation in exif and exif[orientation] == 6:
            im = im.rotate(270, expand=True)
        elif orientation in exif and exif[orientation] == 8:
            im = im.rotate(90, expand=True)
    except Exception as ex:
        logging.debug(ex)

    return im
Ejemplo n.º 16
0
def exif_rotate(image: Image) -> Image:
    if not hasattr(image, "_getexif"):
        return image
    exif_data = image._getexif()
    if exif_data is None:
        return image

    exif_dict = dict(exif_data.items())
    orientation = exif_dict.get(name_to_tag_num["Orientation"])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Ejemplo n.º 17
0
def exif_rotate(image: Image) -> Image:
    if not hasattr(image, '_getexif'):
        return image
    exif_data = image._getexif()
    if exif_data is None:  # nocoverage # don't have a test image for this case, but it happens
        return image

    exif_dict = dict(exif_data.items())
    orientation = exif_dict.get(name_to_tag_num['Orientation'])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Ejemplo n.º 18
0
def exif_rotate(image: Image) -> Image:
    if not hasattr(image, '_getexif'):
        return image
    exif_data = image._getexif()
    if exif_data is None:
        return image

    exif_dict = dict(exif_data.items())
    orientation = exif_dict.get(name_to_tag_num['Orientation'])

    if orientation == 3:
        return image.rotate(180, expand=True)
    elif orientation == 6:
        return image.rotate(270, expand=True)
    elif orientation == 8:
        return image.rotate(90, expand=True)

    return image
Ejemplo n.º 19
0
    def rotate_upright(self, image: Image):
        """
        Rotate a PIL image to upright depending on its current orientation according to EXIF data.
        """
        try:
            for orientation in ExifTags.TAGS.keys():
                if ExifTags.TAGS[orientation] == "Orientation":
                    break
            exif = dict(image._getexif().items())

            orientation = exif[orientation]
            if orientation == 3:
                image = image.rotate(180, expand=True)
            elif orientation == 6:
                image = image.rotate(270, expand=True)
            elif orientation == 8:
                image = image.rotate(90, expand=True)
        except (AttributeError, KeyError) as e:
            pass
        return image
Ejemplo n.º 20
0
    def rotate_image(image: Image):
        """
        画像ファイルをEXIF情報に合わせて回転
        """
        if image is None:
            raise ValueError

        orientation = 1
        exif_info = image._getexif()
        if exif_info:
            orientation = exif_info.get(0x112, 1)

        ans = image

        if orientation == 2:
            # 左右反転
            ans = image.transpose(Image.FLIP_LEFT_RIGHT)
        elif orientation == 3:
            # 180度回転
            ans = image.transpose(Image.ROTATE_180)
        elif orientation == 4:
            # 上下反転
            ans = image.transpose(Image.FLIP_TOP_BOTTOM)
        elif orientation == 5:
            # 左右反転して90度回転
            ans = image.transpose(Image.FLIP_LEFT_RIGHT).transpose(
                Image.ROTATE_90)
        elif orientation == 6:
            # 270度回転
            ans = image.transpose(Image.ROTATE_270)
        elif orientation == 7:
            # 左右反転して270度回転
            ans = image.transpose(Image.FLIP_LEFT_RIGHT).transpose(
                Image.ROTATE_270)
        elif orientation == 8:
            # 90度回転
            ans = image.transpose(Image.ROTATE_90)

        return ans
def extract_exif(image: Image) -> dict:
    """

    Args:
        image:

    Returns:

    """
    try:
        exif_data = image._getexif()
        if exif_data is not None:
            exif = {
                ExifTags.TAGS[k]: decode_byte_exif(v)
                for k, v in exif_data.items() if k in ExifTags.TAGS
            }
        else:
            exif = {}
    except (AttributeError, OSError):
        # Not all file types (e.g. .gif) have exif information.
        exif = {}

    return exif
Ejemplo n.º 22
0
def orientation_correction(image: Image) -> Image:
    """
    Depending on how camera was held some images might get messed up orientation
    after thumbnail function resizes them. Full explanation and solution were
    borrowed from
    https://stackoverflow.com/questions/4228530/pil-thumbnail-is-rotating-my-image
    :param image: Original image
    :return: image
    """
    # only present in JPEGs
    if not hasattr(image, '_getexif'):
        return image

    # returns None if no EXIF data
    e = image._getexif()
    if e is None:
        return image

    # pick correct orientation code from ExifTags
    orientation = None
    for key in ExifTags.TAGS.keys():
        if ExifTags.TAGS[key] == 'Orientation':
            orientation = key
            break

    # get orientation number
    exif = dict(e.items())
    orientation = exif.get(orientation, None)

    if orientation == 3:
        return image.transpose(Image.ROTATE_180)
    if orientation == 6:
        return image.transpose(Image.ROTATE_270)
    if orientation == 8:
        return image.transpose(Image.ROTATE_90)

    return image
Ejemplo n.º 23
0
def get_creation_date(img: Image):
    info = img._getexif()
    for tag in info.keys():
        if TAGS.get(tag, tag) == 'DateTimeOriginal':
            return info[tag]
    return None
Ejemplo n.º 24
0
def set_faux_dpi(image: Image, dpi: int) -> Image:
    """
    Sets the image's DPI Exif metadata without actually changing the image
    """
    print_exif(image)
    image._getexif()
Ejemplo n.º 25
0
def print_exif(image: Image) -> None:
    for (k, v) in image._getexif().items():
        print('%s = %s' % (TAGS.get(k), v))
Ejemplo n.º 26
0
def get_exif(image: Image) -> dict:
    image.verify()
    return image._getexif()