-
Notifications
You must be signed in to change notification settings - Fork 33
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
Request: PictureFrame 2020 New MQTT option #64
Comments
Martin It obviously would be possible in the same way that the other exif info is displayed. However it would need several changes to the code: 1) a field in the db So quite a lot of changes - which begs the question why we hard coded so much in? Which is a good question, in retrospect! For your specific application the folder name containing the image is already available. Can you use that? |
Thanks Paddy. Basically I am looking to display the location of the image. For images that have GPS data then that is working fine, but many of my images do not have GPS data so, at the moment, I have to display the date of the image and then go back to my PC (where the originals are stored) and look up the location for that date. My photos are stored in folders on the PC named by approximate location and date, for example 'Tenerife 2008', 'Malta 2011' and so on. For images without GPS data then that name would be adequate for my purposes. The images on the pi for the picture frame are in folders based on common keywords and contain images from multiple PC folders. My thought was to embed the original folder name in the image metadata and the exif 'UserComment' field seemed a reasonable option (although, I assume that any Ascii type Exif tag would work as well). As I said, I have found a successful method to do this using ExifTool. I wondered, therefore, in the same way that PictureFrame2020geo.py retrieves the Exif GPS data, whether the 'UserComment' data could be retrieved similarly. I take it, however, that the issues that you highlighted would still apply, although all the links you mentioned all point to 'picframe' and not 'pi3d_demos' Martin |
Martin, sorry, I've been concentrating entirely on the picframe version since end of last year so hadn't realised this was all about PictureFrame2020 - I will think again about your question and get back to you! Paddy |
Hi @Duzeper have a look at https://github.com/helgeerbe/picframe. You could store your location infos in the exif title or caption field. I'm not sure if you already use this fields, but if not this would be a good workaround. The new PictureFrame allows to show title, caption, file name, folder, location and date. |
Thanks, I will bear that in mind. However, I am not a developer. My entire, and very limited, knowledge of Linux and Python has come from Pictureframe2020 and I have now largely got it doing what I want (apart from this question obviously) and so I am wary about starting from scratch with a new application. I just thought that, given that PictureFrame2020geo can retrieve Exif GPS data from an image, surely it shouldn't be too difficult to do the same for another Exif field. |
Hi, I can understand not wanting to unscramble the work you've already done and find all the problems with a new version of the app. However there are quite a few improvements to the way the picture frame chaches info so it doesn't have to reload everything from scratch each time, among many others. I don't know which version of PictureFrame2020 you are using but here is a diff of the latest on gitub/pi3d/pi3d_demos compared with a very quick scan through of the things I think you will need to add. I've not attempted to run it yet so there could well be typos and bits of wrong code! PictureFrame2020.py diff --git a/PictureFrame2020.py b/PictureFrame2020.py
index 9293b52..92a599b 100644
--- a/PictureFrame2020.py
+++ b/PictureFrame2020.py
@@ -27,7 +27,7 @@ from PIL import Image, ExifTags, ImageFilter # these are needed for getting exif
import PictureFrame2020config as config
class Pic:
- def __init__(self, fname, orientation=1, mtime=None, dt=None, fdt=None, location="", aspect=1.5):
+ def __init__(self, fname, orientation=1, mtime=None, dt=None, fdt=None, location="", aspect=1.5, user_comment=""):
self.fname = fname
self.orientation = orientation
self.mtime = mtime
@@ -35,6 +35,7 @@ class Pic:
self.fdt = fdt
self.location = location
self.aspect = aspect
+ self.user_comment = user_comment
self.shown_with = None # set to pic_num of image this was paired with
try:
@@ -144,12 +145,13 @@ def tex_load(pic_num, iFiles, size=None):
if pic_num < len(iFiles) - 1: # i.e can't do this on the last image in list
for f_rec in iFiles[pic_num + 1:]:
if f_rec.dt is None or f_rec.fdt is None: # dt and fdt set to None before exif read
- (f_orientation, f_dt, f_fdt, f_location, f_aspect) = get_exif_info(f_rec.fname)
+ (f_orientation, f_dt, f_fdt, f_location, f_aspect, f_user_comment) = get_exif_info(f_rec.fname)
f_rec.orientation = f_orientation
f_rec.dt = f_dt
f_rec.fdt = f_fdt
f_rec.location = f_location
f_rec.aspect = f_aspect
+ f_rec.user_comment = f_user_comment
if f_rec.aspect < 1.0 and f_rec.shown_with is None:
im2 = Image.open(f_rec.fname)
f_rec.shown_with = pic_num
@@ -243,8 +245,9 @@ def get_files(dt_from=None, dt_to=None):
fdt = None
location = ""
aspect = 1.5 # assume landscape aspect until we determine otherwise
+ user_comment = ""
if not config.DELAY_EXIF and EXIF_DATID is not None and EXIF_ORIENTATION is not None:
- (orientation, dt, fdt, location, aspect) = get_exif_info(file_path_name)
+ (orientation, dt, fdt, location, aspect, user_comment) = get_exif_info(file_path_name)
if (dt_from is not None and dt < dt_from) or (dt_to is not None and dt > dt_to):
include_flag = False
if include_flag:
@@ -255,7 +258,8 @@ def get_files(dt_from=None, dt_to=None):
dt,
fdt,
location,
- aspect))
+ aspect,
+ user_comment))
if shuffle:
file_list.sort(key=lambda x: x.mtime) # will be later files last
temp_list_first = file_list[-config.RECENT_N:]
@@ -273,6 +277,7 @@ def get_exif_info(file_path_name, im=None):
orientation = 1
location = ""
aspect = 1.5 # assume landscape aspect until we determine otherwise
+ user_comment = ""
try:
if im is None:
im = Image.open(file_path_name) # lazy operation so shouldn't load (better test though)
@@ -285,13 +290,15 @@ def get_exif_info(file_path_name, im=None):
orientation = int(exif_data[EXIF_ORIENTATION])
if orientation == 6 or orientation == 8:
aspect = 1.0 / aspect # image rotated 270 or 90 degrees
+ if EXIF_USERCOMMENT in exif_data:
+ user_comment = exif_data[EXIF_USERCOMMENT]
if config.LOAD_GEOLOC and geo.EXIF_GPSINFO in exif_data:
location = geo.get_location(exif_data[geo.EXIF_GPSINFO])
except Exception as e: # NB should really check error here but it's almost certainly due to lack of exif data
if config.VERBOSE:
print('trying to read exif', e)
fdt = time.strftime(config.SHOW_TEXT_FM, time.localtime(dt))
- return (orientation, dt, fdt, location, aspect)
+ return (orientation, dt, fdt, location, aspect, user_comment)
def convert_heif(fname):
try:
@@ -307,11 +314,14 @@ def convert_heif(fname):
EXIF_DATID = None # this needs to be set before get_files() above can extract exif date info
EXIF_ORIENTATION = None
+EXIF_USERCOMMENT = None
for k in ExifTags.TAGS:
if ExifTags.TAGS[k] == 'DateTimeOriginal':
EXIF_DATID = k
if ExifTags.TAGS[k] == 'Orientation':
EXIF_ORIENTATION = k
+ if ExifTags.TAGS[k] == 'UserComment':
+ EXIF_USERCOMMENT = k
if config.LOAD_GEOLOC:
import PictureFrame2020geo as geo
@@ -344,6 +354,7 @@ if config.USE_MQTT:
client.subscribe("{}text_on".format(id), qos=0) # toggle file name on and off. payload text show time in seconds
client.subscribe("{}date_on".format(id), qos=0) # toggle date (exif if avail else file) on and off. payload show time
client.subscribe("{}location_on".format(id), qos=0) # toggle location (if enabled) on and off. payload show time
+ client.subscribe("{}usercomment_on".format(id), qos=0) # toggle location (if enabled) on and off. payload show time
client.subscribe("{}text_off".format(id), qos=0) # turn all name, date, location off
client.subscribe("{}text_refresh".format(id), qos=0) # restarts current slide showing text set above
client.subscribe("{}brightness".format(id), qos=0) # set shader brightness
@@ -433,6 +444,10 @@ if config.USE_MQTT:
config.SHOW_TEXT_TM = float_msg if float_msg > 2.0 else 0.33 * config.TIME_DELAY
config.SHOW_TEXT ^= 4
text_start_tm = -0.1
+ elif message.topic == "{}usercomment_on".format(id):
+ config.SHOW_TEXT_TM = float_msg if float_msg > 2.0 else 0.33 * config.TIME_DELAY
+ config.SHOW_TEXT ^= 16
+ text_start_tm = -0.1
elif message.topic == "{}text_off".format(id):
config.SHOW_TEXT = 0
text_start_tm = -0.1
@@ -588,6 +603,8 @@ while DISPLAY.loop_running():
info_strings.append(loc_string)
if (config.SHOW_TEXT & 8) == 8: # folder
info_strings.append(sanitize_string(os.path.basename(os.path.dirname(iFiles[pic_num].fname))))
+ if (config.SHOW_TEXT & 16) == 16: # usercomment
+ info_strings.append(sanitize_string(iFiles[pic_num].user_comment))
if paused:
info_strings.append("PAUSED") PictureFrame2020config.py diff --git a/PictureFrame2020config.py b/PictureFrame2020config.py
index 8e75b19..0bf52b2 100644
--- a/PictureFrame2020config.py
+++ b/PictureFrame2020config.py
@@ -25,6 +25,8 @@ def parse_show_text(txt):
show_text |= 4
if "folder" in txt:
show_text |= 8
+ if "usercomment" in txt:
+ show_text |= 16
return show_text
# NB the reason that absolute paths are used here is because relative ones can lead
@@ -55,7 +57,7 @@ parse.add_argument("-r", "--reshuffle_num", default=1, type=int, help="times thr
parse.add_argument("-s", "--show_text_tm", default=6.0, type=float, help="time to show text over the image")
parse.add_argument( "--show_text_fm", default="%b %d, %Y", help="format to show date over the image")
parse.add_argument( "--show_text_sz", default=40, type=int, help="text character size")
-parse.add_argument( "--show_text", default="date folder location", help="show text, include combination of words: name, date, location")
+parse.add_argument( "--show_text", default="name date folder location usercomment", help="show text, include combination of words: name, date, location")
parse.add_argument( "--text_width", default=90, type=int, help="number of character before breaking into new line")
parse.add_argument("-t", "--fit", default=False, type=str_to_bool, help="shrink to fit screen i.e. don't crop")
parse.add_argument("-u", "--kenburns", default=False, type=str_to_bool, help="will set FIT->False and BLUR_EDGES->False") |
Thanks. I'll look into that. However, at the moment, with, at last, some good weather, my garden is calling me. |
Is there any way to display the contents of an Exif field (specifically 0x9286 UserComment), using MQTT, in the same way as (Date, Location, Filename), which are all working great.
I am using ExifTool to add the image's containing folder name to this field and it would be nice to have an MQTT option to display the contents of that field.
Martin Dashper
The text was updated successfully, but these errors were encountered: