-
Notifications
You must be signed in to change notification settings - Fork 35
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Heic support and make tag #165
Changes from all commits
d1db166
ea7d078
fdbabf8
b34039b
2ed18b4
617ce85
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,7 +9,7 @@ class ImageCache: | |
|
||
EXTENSIONS = ['.png','.jpg','.jpeg','.heif','.heic'] | ||
EXIF_TO_FIELD = {'EXIF FNumber': 'f_number', | ||
'EXIF Make': 'make', | ||
'Image Make': 'make', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure which one is correct here (haven't done any research). I will say that my db currently DOES contain some records where the current There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I checked for Apple, Canon, Sony. I only find "Image Make"
Never "Make" in EXIF:
Do you have an example image for me? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See exifread: Note that the dictionary keys are the IFD name followed by the tag name. For example:
If you check exiftool tags description you will find the "Group" column:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Here's a few examples. Looks like about 70% of my (frame) images have Ultimately, we might have to be a bit more clever with some of the info and cascade through a number of tags looking for a definition... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the example. Checking the standard I would say, that "Make" belongs to 0th IFD (Image) group. And is not defined for Exif IFD (Exif). So in my understanding your sample images are not correct. You are using Picasa, this Software is no longer maintained, isn't it? What we can easily do is look first in the correct group and as fallback search in the other. Assuming we are focusing only on "Exif" and "Image" group. exifread is returning everything anyway:
But I wouldn't do this for other Groups like "Thumbnail" There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm definitely not a Picasa user (and, yeah, I think it's been gone for a long time), though I did see it noted in the
Agreed. That's exactly what I meant with my earlier statement... Ultimately, we might have to be a bit more clever with some of the info and cascade through a number of tags looking for a definition...
Agreed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yeah, I think I agree with you (although, the EXIF spec doc is not a fun read...) I'll try to get to the bottom of what's creating my questionable EXIF data, although I suspect it's coming from "ON1 Photo Raw", which is my primary RAW converter and image editor. Although, that's surprising if so, as it's a widely used package with regular updates... |
||
'Image Model': 'model', | ||
'EXIF ExposureTime': 'exposure_time', | ||
'EXIF ISOSpeedRatings': 'iso', | ||
|
@@ -454,7 +454,8 @@ def __get_exif_info(self, file_path_name): | |
e['orientation'] = exifs.get_orientation() | ||
|
||
width, height = exifs.get_size() | ||
if e['orientation'] in (5, 6, 7, 8): | ||
ext = os.path.splitext(file_path_name)[1].lower() | ||
if ext not in ('.heif','.heic') and e['orientation'] in (5, 6, 7, 8): | ||
width, height = height, width # swap values | ||
e['width'] = width | ||
e['height'] = height | ||
|
@@ -466,7 +467,7 @@ def __get_exif_info(self, file_path_name): | |
e['exposure_time'] = exifs.get_exif('EXIF ExposureTime') | ||
e['iso'] = exifs.get_exif('EXIF ISOSpeedRatings') | ||
e['focal_length'] = exifs.get_exif('EXIF FocalLength') | ||
e['rating'] = exifs.get_exif('EXIF Rating') | ||
e['rating'] = exifs.get_exif('Image Rating') | ||
e['lens'] = exifs.get_exif('EXIF LensModel') | ||
e['exif_datetime'] = None | ||
val = exifs.get_exif('EXIF DateTimeOriginal') | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
import os | ||
import numpy as np | ||
from PIL import Image, ImageFilter, ImageFile | ||
from picframe import mat_image | ||
from picframe import mat_image, get_image_meta | ||
from datetime import datetime | ||
|
||
# supported display modes for display switch | ||
|
@@ -173,29 +173,6 @@ def clock_is_on(self): | |
def clock_is_on(self, val): | ||
self.__show_clock = val | ||
|
||
def __check_heif_then_open(self, fname): | ||
ext = os.path.splitext(fname)[1].lower() | ||
if ext in ('.heif','.heic'): | ||
try: | ||
import pyheif | ||
|
||
heif_file = pyheif.read(fname) | ||
image = Image.frombytes(heif_file.mode, heif_file.size, heif_file.data, | ||
"raw", heif_file.mode, heif_file.stride) | ||
if image.mode not in ("RGB", "RGBA"): | ||
image = image.convert("RGB") | ||
return image | ||
except: | ||
self.__logger.warning("Failed attempt to convert %s \n** Have you installed pyheif? **", fname) | ||
else: | ||
try: | ||
image = Image.open(fname) | ||
if image.mode not in ("RGB", "RGBA"): # mat system needs RGB or more | ||
image = image.convert("RGB") | ||
except: # for whatever reason | ||
image = None | ||
return image | ||
|
||
# Concatenate the specified images horizontally. Clip the taller | ||
# image to the height of the shorter image. | ||
def __create_image_pair(self, im1, im2): | ||
|
@@ -210,7 +187,11 @@ def __create_image_pair(self, im1, im2): | |
dst.paste(im2, (im1.width + sep, 0)) | ||
return dst | ||
|
||
def __orientate_image(self, im, orientation): | ||
def __orientate_image(self, im, pic): | ||
ext = os.path.splitext(pic.fname)[1].lower() | ||
if ext in ('.heif','.heic'): # heif and heic images are converted to PIL.Image obects and are alway in correct orienation | ||
return im | ||
orientation = pic.orientation | ||
if orientation == 2: | ||
im = im.transpose(Image.FLIP_LEFT_RIGHT) | ||
elif orientation == 3: | ||
|
@@ -272,15 +253,18 @@ def __tex_load(self, pics, size=None): | |
|
||
# Load the image(s) and correct their orientation as necessary | ||
if pics[0]: | ||
im = self.__check_heif_then_open(pics[0].fname) | ||
if pics[0].orientation != 1: | ||
im = self.__orientate_image(im, pics[0].orientation) | ||
im = get_image_meta.GetImageMeta.get_image_object(pics[0].fname) | ||
if im is None: | ||
return None | ||
if pics[0].orientation != 1: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we wanted to shift the "heic orientation" issue to load/display time, it'd need to happen right here somewhere. Either we wouldn't call |
||
im = self.__orientate_image(im, pics[0]) | ||
|
||
if pics[1]: | ||
im2 = self.__check_heif_then_open(pics[1].fname) | ||
im2 = get_image_meta.GetImageMeta.get_image_object(pics[1].fname) | ||
if im2 is None: | ||
return None | ||
if pics[1].orientation != 1: | ||
im2 = self.__orientate_image(im2, pics[1].orientation) | ||
im2 = self.__orientate_image(im2, pics[1]) | ||
|
||
screen_aspect, image_aspect, diff_aspect = self.__get_aspect_diff(size, im.size) | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like it should work to cascade between the two groups, so maybe this is all we need for now. It might be nice (for future) to have something like
get_exif_fuzzy
(or similar) that used a dictionary keyed by a generic tag name with the value being a list of prioritized group/tag names to search for a match. So, something like this, for example:{'make': ['Image Make', 'EXIF Make'], 'model': ['Image Model', 'EXIF Model']}