def renameImageFile(key, oldFileName, newFileName, outputFolder, payloadFolder = None): """ Accepts an image path and copies while renaming it key = the key from the recordDict, which should correspond to the field number. Passing this to avoid addtl. work. oldFileName = the field-number-named file which needs to be renamed and moved newFileNAme = the desired new name after moving outputFolder = the folder to save the catalog-number-named file payloadFolder = the folder to congregate to be transfered files, if not passed presumes it is the same as outputFolder """ if payloadFolder == None: payloadFolder = outputFolder newFileNames = [] #start with an empty list.... for destFolder in set([outputFolder, payloadFolder]): newFileNames.append(str(destFolder + '/{}.jpg'.format(newFileName))) #Build a list of paths to copy the orig file to. # see this example for concerns about loss of metadata upon image copy: # https://stackoverflow.com/questions/6106303/how-to-rename-a-file-and-preserve-creation-date-in-python stat = os.stat(oldFileName) #Take note of creation and modification metadata from initial file for outputName in newFileNames: # for each filepath we're copying to os.makedirs(os.path.dirname(outputName), exist_ok=True) shutil.copy2(oldFileName, outputName) # copy the origional and rename it according to the outputName # insert metadata metaDataDict = {'otherCatalogNumber':key} #This dict can be altered to add ... everything? zeroth_ifd = {270: str(metaDataDict)} #converting dict to string to embed it into the same field exif_bytes = piexif.dump({"0th":zeroth_ifd}) os.utime(outputName, (stat.st_atime, stat.st_mtime)) #Write orig creation and modification metadata to the copied file #debugging creation time metadata loss # print(stat) # print(os.stat(outputName)) piexif.insert(exif_bytes,outputName)
def write_gps_exif(coordinate, altitude, read_image_path, write_image_path): """Write gps exif data into an image Args: :param coordinate: GPS coordinates in fractions (dict) :param altitude: Altitude in fractions (list) :param read_image_path: Absolute path of image that needs to be geotagged (str) :param write_image_path: Absolute path of geotagged image (str) """ exif_dict = piexif.load(read_image_path) gps_ifd = { piexif.GPSIFD.GPSLatitudeRef: coordinate['Lat']['Hem'], piexif.GPSIFD.GPSLatitude: ((coordinate['Lat']['Deg']), (coordinate['Lat']['Min']), (coordinate['Lat']['Sec'])), piexif.GPSIFD.GPSLongitude: ((coordinate['Lng']['Deg']), (coordinate['Lng']['Min']), (coordinate['Lng']['Sec'])), piexif.GPSIFD.GPSLongitudeRef: coordinate['Lng']['Hem'], piexif.GPSIFD.GPSAltitude: altitude } exif_dict['GPS'] = gps_ifd exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, write_image_path)
def setgeoimage(data, lat, lon, imagedescription="", usercomment="", dt=None): exif_dict = piexif.load(data) #for ifd in ("0th", "Exif", "GPS", "1st"): # for tag in exif_dict[ifd]: # print tag # print(piexif.TAGS[ifd][tag]["name"], exif_dict[ifd][tag]) # #lat,lon=get_geo(exif_dict) #print "lat lon",lat,lon if dt is None: exif_dict["0th"][piexif.ImageIFD.DateTime] = datetime.utcnow( ).strftime("%Y:%m:%d %H:%M:%S") else: exif_dict["0th"][piexif.ImageIFD.DateTime] = dt.strftime( "%Y:%m:%d %H:%M:%S") set_geo(exif_dict, lat, lon) exif_dict["Exif"][ piexif.ExifIFD.UserComment] = chr(0x55) + chr(0x4E) + chr(0x49) + chr( 0x43) + chr(0x4F) + chr(0x44) + chr(0x45) + chr(0x00) + usercomment exif_dict["0th"][piexif.ImageIFD.ImageDescription] = imagedescription exif_bytes = piexif.dump(exif_dict) new_data = io.BytesIO(data) piexif.insert(exif_bytes, data, new_data) return new_data.getvalue()
def test_piexif( input_file_name, output_file_name, args ): """ Tests Exif manipulation using Piexif performing JPEG I/O with buffered reads and writes. Takes 3 arguments: input_file_name - Path of input JPEG file. output_file_name - Path of output JPEG file. args - Dictionary of arguments provided to the test. This is unused. Returns nothing. """ import piexif jpeg_data = open( input_file_name, "rb" ).read() o = io.BytesIO() # use piexif to extract our Exif data and insert it back into the raw JPEG # byte stream. exif_dict = piexif.load( input_file_name ) exif_dict['GPS'][2] = ((1, 1), (2, 1), (3, 1)) exif_dict['GPS'][4] = ((4, 1), (5, 1), (6, 1)) exif_bytes = piexif.dump( exif_dict ) piexif.insert( exif_bytes, jpeg_data, o ) with open( output_file_name, "wb" ) as file: file.write( o.getvalue() ) munged_jpeg_data = open( output_file_name, "rb" ).read() munged_exif_dict = piexif.load( output_file_name ) munged_exif_bytes = piexif.dump( munged_exif_dict )
def combine(self, essence: IO, metadata_by_format: Mapping[str, Mapping]) -> IO: result = io.BytesIO() with tempfile.NamedTemporaryFile(mode='w+b') as tmp: tmp.write(essence.read()) tmp.flush() try: exif_metadata = piexif.load(tmp.name) except (piexif.InvalidImageDataError, ValueError): raise UnsupportedFormatError('Unsupported essence format.') for metadata_format, metadata in metadata_by_format.items(): if metadata_format not in self.formats: raise UnsupportedFormatError(f'Metadata format {metadata_format!r} is not supported.') for madam_key, madam_value in metadata.items(): if madam_key not in ExifMetadataProcessor.metadata_to_exif: continue ifd_key, exif_key = ExifMetadataProcessor.metadata_to_exif[madam_key] if ifd_key not in exif_metadata: exif_metadata[ifd_key] = {} _, convert_to_exif = ExifMetadataProcessor.converters[madam_key] exif_metadata[ifd_key][exif_key] = convert_to_exif(madam_value) try: piexif.insert(piexif.dump(exif_metadata), tmp.name) except (piexif.InvalidImageDataError, ValueError): raise UnsupportedFormatError(f'Could not write metadata: {metadata_by_format!r}') tmp.seek(0) shutil.copyfileobj(tmp, result) result.seek(0) return result
def metadata_erase(img, exif, tags): exif = piexif.load(exif) new_exif = adjust_exif2(tags,exif) new_bytes = piexif.dump(new_exif) outputImage = io.BytesIO() piexif.insert(new_bytes, img, outputImage) return outputImage
def write_image(image, fname, pt, lat, lon, fov, pan): """Write the image corresponding to a time and space point to fname.""" dt = pt[0] s = pt[7] image.save(fname) datestamp, time = dt.split(" ") h, m, s = time.split(":") timestamp = ((int(h), 1), (int(m), 1), (int(s), 1)) lat_pretty = ephem.degrees(math.radians(lat)) lat_h, lat_m, lat_s = str(lat_pretty).split(":") lat_fmt = ((int(lat_h), 1), (int(lat_m), 1), (int(float(lat_s)), 1)) lon_pretty = ephem.degrees(math.radians(lon)) lon_h, lon_m, lon_s = str(lon_pretty).split(":") lon_fmt = ((-int(lon_h), 1), (int(lon_m), 1), (int(float(lon_s)), 1)) exif = piexif.load(fname) # Update the EXIF GPS time and date exif['GPS'][piexif.GPSIFD.GPSLatitude] = lat_fmt exif['GPS'][piexif.GPSIFD.GPSLatitudeRef] = 'N' exif['GPS'][piexif.GPSIFD.GPSLongitude] = lon_fmt exif['GPS'][piexif.GPSIFD.GPSLongitudeRef] = 'W' exif['GPS'][piexif.GPSIFD.GPSDateStamp] = datestamp exif['GPS'][piexif.GPSIFD.GPSTimeStamp] = timestamp t = get_phase(s) # Write custom data into the MakerNote exif['Exif'][piexif.ExifIFD.MakerNote] = "%s|%d, %d|%d" % (t, fov, pan[0], pan[1]) b = piexif.dump(exif) piexif.insert(b, fname)
def add_gps_tags(path: str, gps_tags: {str: any}): """This method will add gps tags to the photo found at path""" exif_dict = piexif.load(path) for tag, tag_value in gps_tags.items(): exif_dict["GPS"][tag] = tag_value exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, path)
def setgeoimage(data,lat,lon,imagedescription="",usercomment="",dt=None): exif_dict = piexif.load(data) #for ifd in ("0th", "Exif", "GPS", "1st"): # for tag in exif_dict[ifd]: # print tag # print(piexif.TAGS[ifd][tag]["name"], exif_dict[ifd][tag]) # #lat,lon=get_geo(exif_dict) #print "lat lon",lat,lon if dt is None: exif_dict["0th"][piexif.ImageIFD.DateTime]=datetime.utcnow().strftime("%Y:%m:%d %H:%M:%S") else: exif_dict["0th"][piexif.ImageIFD.DateTime]=dt.strftime("%Y:%m:%d %H:%M:%S") set_geo(exif_dict, lat, lon) exif_dict["Exif"][piexif.ExifIFD.UserComment]=chr(0x55)+chr(0x4E)+chr(0x49)+chr(0x43)+chr(0x4F)+chr(0x44)+chr(0x45)+chr(0x00)+usercomment exif_dict["0th"][piexif.ImageIFD.ImageDescription]=imagedescription exif_bytes = piexif.dump(exif_dict) new_data=io.BytesIO(data) piexif.insert(exif_bytes, data, new_data) return new_data.getvalue()
def set_gps_location(file_name, lat, lng, altitude): """Adds GPS position as EXIF metadata Keyword arguments: file_name -- image file lat -- latitude (as float) lng -- longitude (as float) altitude -- altitude (as float) """ lat_deg = to_deg(lat, ["S", "N"]) lng_deg = to_deg(lng, ["W", "E"]) exiv_lat = (change_to_rational(lat_deg[0]), change_to_rational(lat_deg[1]), change_to_rational(lat_deg[2])) exiv_lng = (change_to_rational(lng_deg[0]), change_to_rational(lng_deg[1]), change_to_rational(lng_deg[2])) gps_ifd = { piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0), piexif.GPSIFD.GPSAltitudeRef: 1, piexif.GPSIFD.GPSAltitude: change_to_rational(round(altitude)), piexif.GPSIFD.GPSLatitudeRef: lat_deg[3], piexif.GPSIFD.GPSLatitude: exiv_lat, piexif.GPSIFD.GPSLongitudeRef: lng_deg[3], piexif.GPSIFD.GPSLongitude: exiv_lng, } exif_dict = {"GPS": gps_ifd} exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, file_name)
def rename_plant_in_exif_tags(image: Photo, plant_name_old: str, plant_name_new: str) -> None: """ renames plant in image's plant tags; both in files and in images directory; preserves last modified date of image file """ # we want to preserve the file's last-change-date modified_time_seconds = modified_date(image.path_full_local) # seconds # get a new list of plants for the image and convert it to exif tag syntax image.tag_authors_plants.remove(plant_name_old) image.tag_authors_plants.append(plant_name_new) tag_authors_plants = ';'.join(image.tag_authors_plants).encode('utf-8') # load file's current exif tags and overwrite the authors tag used for saving plants exif_dict = piexif.load(image.path_full_local) exif_dict['0th'][315] = tag_authors_plants # Windows Authors Tag # update the file's exif tags physically exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, image.path_full_local) # reset file's last modified date to the previous date set_modified_date(image.path_full_local, modified_time_seconds) # set access and modifide date
def jpegexifhide(): global filename, new_file code = "vizsla" img = Image.open(filename) exifdata = img.getexif() #print(exifdata) #what = img.info.get('icc_profile', '') #print(what) #print(img.mode) src = hiddenmessage xorWord = lambda ss, cc: ''.join(chr(ord(s) ^ ord(c)) for s, c in zip(ss, cc * 100)) encrypt = xorWord(src, code) new = encrypt.encode('ascii') encoded = base64.b64encode(new) b64message = encoded.decode('ascii') exif_dict = piexif.load(filename) exif_dict["0th"][piexif.ImageIFD.HostComputer] = b64message exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, filename, new_file="embedded_exif:" + filename) new_file = "embedded_exif_" + filename img.save(new_file, exif=exif_bytes) newww = Image.open(new_file) newexif = newww.getexif() print(newexif)
def test_insert(self): """Can PIL open WebP that is inserted exif?""" IMAGE_DIR = "tests/images/" OUT_DIR = "tests/images/out/" files = [ "tool1.webp", "pil1.webp", "pil2.webp", "pil3.webp", "pil_rgb.webp", "pil_rgba.webp", ] exif_dict = { "0th": { piexif.ImageIFD.Software: b"PIL", piexif.ImageIFD.Make: b"Make", } } exif_bytes = piexif.dump(exif_dict) for filename in files: try: Image.open(IMAGE_DIR + filename) except: print("Pillow can't read {0}".format(filename)) continue piexif.insert(exif_bytes, IMAGE_DIR + filename, OUT_DIR + "ii_" + filename) Image.open(OUT_DIR + "ii_" + filename)
def download_photos(): ssl._create_default_https_context = ssl._create_unverified_context #Prep the download folder folder = 'photos/' if not os.path.exists(folder): os.makedirs(folder) print("Saving photos to " + folder) #Download the photos with open('tagged.json') as json_file: data = json.load(json_file) for i, d in enumerate(data['tagged']): if d['media_type'] == 'image': #Save new file if d['fb_date'] == "Today": filename_date = datetime.today().strftime('%Y-%m-%d') elif d['fb_date'] == "Yesterday": filename_date = datetime.today() - timedelta(days=1) filename_date = filename_date.strftime('%Y-%m-%d') else: filename_date = parse(d['fb_date']).strftime("%Y-%m-%d") img_id = d['media_url'].split('_')[1] new_filename = folder + filename_date + '_' + img_id + '.jpg' if os.path.exists(new_filename): print("Already Exists (Skipping): %s" % (new_filename)) else: delay = 1 while True: try: print("Downloading " + d['media_url']) img_file = wget.download(d['media_url'], new_filename, False) break except (TimeoutError, urllib.error.URLError) as e: print("Sleeping for {} seconds".format(delay)) time.sleep(delay) delay *= 2 #Update EXIF Date Created exif_dict = piexif.load(img_file) if d['fb_date'] == "Today": exif_date = datetime.today().strftime( "%Y:%m:%d %H:%M:%S") elif d['fb_date'] == "Yesterday": exif_date = datetime.today() - timedelta(days=1) exif_date = exif_date.strftime("%Y:%m:%d %H:%M:%S") else: exif_date = parse( d['fb_date']).strftime("%Y:%m:%d %H:%M:%S") img_desc = d['fb_caption'] + '\n' + d[ 'fb_tags'] + '\n' + d['fb_url'].split("&")[0] exif_dict['Exif'][ piexif.ExifIFD.DateTimeOriginal] = exif_date exif_dict['0th'][piexif.ImageIFD.Copyright] = ( d['user_name'] + ' (' + d['user_url']) + ')' exif_dict['0th'][ piexif.ImageIFD.ImageDescription] = img_desc.encode( 'utf-8') piexif.insert(piexif.dump(exif_dict), img_file) print(str(i + 1) + ') Added ' + new_filename)
def saveImage(self): self.flagEdit = 0 self.addNightState() #self.moveImageToFolder() exif_dict = piexif.load(self.imagepath) labelList = [] #print self.bboxList for bbox in self.bboxList: if len(bbox) == self.lenLableContent and type(bbox) != str: labelList.append(" ".join(str(x) for x in bbox)) if bbox == 'NIGHT' or \ bbox == 'DAY' : labelList.append(bbox) #print "label list: ",labelList label = "#".join(labelList) #print 'BBox List : ',self.bboxList print 'Label new : ', label exif_dict['Exif'][37510] = label exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, self.imagepath) # with open(self.labelfilename, 'w') as f: # f.write('%d\n' %len(self.bboxList)) # for bbox in self.bboxList: # f.write(' '.join(map(str, bbox)) + '\n') print 'Image No. %d saved' % (self.cur)
def download_album(account, password, main_folder_path): cookie_object = Cookie(account=account, password=password) for album_name, album_URL in Album( cookie_object=cookie_object).iterate_album_info(): print("Working on album {} ...".format(album_name)) album_folder_path = os.path.join(main_folder_path, album_name) os.makedirs(album_folder_path, exist_ok=True) for image_name, image_URL_tuple, image_time in Image( cookie_object=cookie_object, album_URL=album_URL).iterate_image_info(): image_file_path = os.path.join(album_folder_path, image_name) if os.path.isfile(image_file_path): continue print("Working on image {} ...".format(image_name)) for image_URL in image_URL_tuple: download_image(image_URL, image_file_path) if os.path.isfile(image_file_path): break if not os.path.isfile(image_file_path): print("Failed to download image {}!".format(image_name)) continue # Insert EXIF information datetime_object = datetime.strptime(image_time, "%a %b %d %H:%M:%S %Z %Y") exif_ifd = { piexif.ExifIFD.DateTimeOriginal: datetime_object.isoformat(" ") } exif_dict = {"Exif": exif_ifd} exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, image_file_path)
def update_titles(self, files): for file in files: self.progress_bar["value"] += (100 / self.progress_bar.length) self.tkinter_root.update_idletasks() filepath = Path(self.directory) / file if not filepath.suffix.lower().endswith(('.jpg', '.jpeg')): continue try: im = Image.open(filepath) except (OSError): print("Could not open/read file: ", filepath) continue if "exif" not in im.info.keys(): continue exif_dict = piexif.load(im.info["exif"]) title_field = file.rpartition(".")[0] exif_dict["0th"].update( {piexif.ImageIFD.ImageDescription: title_field}) exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, im.filename)
def write_datetime(r, media_file_path): try: exif_update = 0 exif_dict = piexif.load(media_file_path) # If media has no Exif datetime, add one based on timestamp if piexif.ExifIFD.DateTimeOriginal not in exif_dict['Exif']: exif_date = time.strftime("%Y:%m:%d %H:%M:%S", time.localtime(r['ts_taken'])) exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = exif_date exif_update = 1 # If there's a description, add it to file Exif if r['description'] != '': exif_dict['0th'][piexif.ImageIFD.ImageDescription] = r[ "description"].encode('utf-8') exif_update = 1 if exif_update == 1: piexif.insert(piexif.dump(exif_dict), media_file_path) db['media_files'].update(r['media_path'], {"exif": 'Updated Exif'}, alter=True) else: db['media_files'].update(r['media_path'], {"exif": 'Original Exif'}, alter=True) except: db['media_files'].update(r['media_path'], {"exif": 'No Exif'}, alter=True) #Always update file modified date (master catch-all for timelines) os.utime(media_file_path, (r['ts_taken'], ) * 2)
def download_media(url, dir, file_name, otime): s = "\rdownloading %s -> %05.2f%% " chunk_size = 1024 if otime: exif_ifd = {piexif.ExifIFD.DateTimeOriginal: otime} exif_dict = {"Exif": exif_ifd} exif_bytes = piexif.dump(exif_dict) with closing(requests.get(url, stream=True)) as r: extension = "jpg" if "content-type" in r.headers: content_type = r.headers["content-type"] extension = content_type[content_type.find("/") + 1:] total_len = math.inf if "content-length" in r.headers: total_len = int(r.headers["content-length"]) current_len = 0 file_name = purge_file_name(file_name) with _lock: if not os.path.exists(dir): os.makedirs(dir) file_name = os.path.join(dir, "%s.%s" % (file_name, extension)) with open(file_name, "wb") as f: for data in r.iter_content(chunk_size): f.write(data) current_len += len(data) percent = 100 * current_len / total_len print(s % (url, percent), end="") if otime: piexif.insert(exif_bytes, file_name) print("\n%s is downloaded" % url)
def set_gps_location(image, lat, lng, altd): lat_deg = convert_to_deg(lat, ["S", "N"]) lng_deg = convert_to_deg(lng, ["W", "E"]) exiv_lat = (convert_to_rational(lat_deg[0]), convert_to_rational(lat_deg[1]), convert_to_rational(lat_deg[2])) exiv_lng = (convert_to_rational(lng_deg[0]), convert_to_rational(lng_deg[1]), convert_to_rational(lng_deg[2])) gps_ifd = { piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0), piexif.GPSIFD.GPSAltitudeRef: 1, piexif.GPSIFD.GPSAltitude: convert_to_rational(round(altd)), piexif.GPSIFD.GPSLatitudeRef: lat_deg[3], piexif.GPSIFD.GPSLatitude: exiv_lat, piexif.GPSIFD.GPSLongitudeRef: lng_deg[3], piexif.GPSIFD.GPSLongitude: exiv_lng, } gps_exif = {"GPS": gps_ifd} # get original exif data first exif_data = piexif.load(image) # update original exif data to include GPS tag exif_data.update(gps_exif) exif_bytes = piexif.dump(exif_data) piexif.insert(exif_bytes, image)
def modify(filename, latitude, longitude, altitude, yaw, roll, pitch): image_dict = piexif.load(filename) du_lat, fen_lat, miao_lat = duTodufenmiao(latitude) du_long, fen_long, miao_long = duTodufenmiao(longitude) altitude = int(altitude) yaw = abs(int(yaw * 100)) # 不能写入负数,当前求绝对值,应该用反码 roll = abs(int(roll * 100)) pitch = abs(int(pitch * 100)) gps_ifd = { piexif.GPSIFD.GPSVersionID: (2, 0), piexif.GPSIFD.GPSLatitudeRef: 'N', piexif.GPSIFD.GPSLatitude: ((du_lat, 1), (fen_lat, 1), (miao_lat, 100)), piexif.GPSIFD.GPSLongitudeRef: 'E', piexif.GPSIFD.GPSLongitude: ((du_long, 1), (fen_long, 1), (miao_long, 100)), piexif.GPSIFD.GPSAltitudeRef: 0, piexif.GPSIFD.GPSAltitude: (altitude, 1), piexif.GPSIFD.GPSDOP: (30, 1), piexif.GPSIFD.GPSSpeed: (yaw, 100), piexif.GPSIFD.GPSTrack: (roll, 100), piexif.GPSIFD.GPSImgDirection: (pitch, 100) } dateStamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") image_dict['GPS'] = gps_ifd image_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = dateStamp image_byte = piexif.dump(image_dict) piexif.insert(image_byte, filename)
def set_gps_location(file_name, lat, lng, altitude): """Adds GPS position as EXIF metadata Keyword arguments: file_name -- image file lat -- latitude (as float) lng -- longitude (as float) altitude -- altitude (as float) """ lat_deg, ref_lat = to_deg(lat, ["S", "N"]) lng_deg, ref_lng = to_deg(lng, ["W", "E"]) exif_lat = list(map(change_to_rational, lat_deg)) exif_lng = list(map(change_to_rational, lng_deg)) ref = 1 if altitude < 0 else 0 gps_ifd = { piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0), piexif.GPSIFD.GPSAltitudeRef: ref, piexif.GPSIFD.GPSAltitude: change_to_rational(abs(altitude)), piexif.GPSIFD.GPSLatitudeRef: ref_lat, piexif.GPSIFD.GPSLatitude: exif_lat, piexif.GPSIFD.GPSLongitudeRef: ref_lng, piexif.GPSIFD.GPSLongitude: exif_lng, } exif_dict = {"GPS": gps_ifd} exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, file_name)
def date_from_filename(): Filenames = glob.glob('./*.jpg') print(Filenames[0]) for Filename in Filenames: print("Processing", Filename, end='\r') ImageDataFromName = Filename[2:-4].split('-') Year = ImageDataFromName[1][:4] Month = ImageDataFromName[1][4:6] Day = ImageDataFromName[1][6:8] Seconds = int(ImageDataFromName[2][2:]) * 5 Hours = int(Seconds / 3600) Seconds = Seconds % 3600 Minutes = int(Seconds / 60) Seconds = Seconds % 60 OriginalDate = u"{y}:{M}:{d} {h}:{m}:{s}".format(y=Year, M=Month, d=Day, h=Hours, m=Minutes, s=Seconds) ExifData = piexif.load(Filename) ExifData['Exif'] = {piexif.ExifIFD.DateTimeOriginal: OriginalDate} ExifBytes = piexif.dump(ExifData) piexif.insert(ExifBytes, Filename)
def date_manual(): filenames = glob.glob('./*.jpg') year = get_date_component("Year: ", DEFAULT_YEAR) month = get_date_component("Month: ", DEFAULT_MONTH) day = get_date_component("Day: ", DEFAULT_DAY) hours = get_date_component("Hour: ", DEFAULT_HOUR) minutes = get_date_component("Minutes: ", DEFAULT_MINUTE) seconds = get_date_component("Seconds: ", DEFAULT_SECOND) date_entered = "{y}:{M}:{d} {h}:{m}:{s}".format(y=year, M=month, d=day, h=hours, m=minutes, s=seconds) n_files = 0 if prompt_confirm("\nSetting capture date to " + date_entered + "."): for filename in filenames: print("Processing", filename, end='\r') date_entered = u"{y}:{M}:{d} {h}:{m}:{s}".format(y=year, M=month, d=day, h=hours, m=minutes, s=seconds) exif_data = piexif.load(filename) exif_data['Exif'] = {piexif.ExifIFD.DateTimeOriginal: date_entered} exif_bytes = piexif.dump(exif_data) piexif.insert(exif_bytes, filename) n_files += 1 input("Edited {} files. Press enter to continue ".format(n_files))
def override_date(file_path, year_month_date): year, month, date = year_month_date no_ext_file_path, ext = os.path.splitext(file_path) _, file_name = os.path.split(no_ext_file_path) prog = re.compile(".*([0-9]+)") m = prog.match(file_name) if m: index = int(m.group(1)) hour = (int(index / (60 * 60)) % 24) minute = (int(index / 60) % 60) sec = index % 60 offset_hour = 12 + hour import piexif exif_dict = piexif.load(file_path) new_date = "{:04}:{:02}:{:02} {:02}:{:02}:{:02}".format( year, month, date, offset_hour, minute, sec) exif_data = exif_dict["Exif"] exif_data[piexif.ExifIFD.DateTimeOriginal] = new_date exif_data[piexif.ExifIFD.DateTimeDigitized] = new_date exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, file_path) change_time.set_time(file_path, int(year), int(month), int(date), offset_hour, minute, sec, 0)
def SetGPSLocation(fileName, lat, lng): # altitude """Adds GPS position as EXIF metadata Keyword arguments: fileName -- image file lat -- latitude (as float) lng -- longitude (as float) altitude -- altitude (as float) """ latDeg = ToDeg(lat, ["S", "N"]) lngDeg = ToDeg(lng, ["W", "E"]) exivLat = (ChangeToRational(latDeg[0]), ChangeToRational(latDeg[1]), ChangeToRational(latDeg[2])) exivLng = (ChangeToRational(lngDeg[0]), ChangeToRational(lngDeg[1]), ChangeToRational(lngDeg[2])) gpsIfd = { piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0), piexif.GPSIFD.GPSAltitudeRef: 1, # piexif.GPSIFD.GPSAltitude: ChangeToRational(round(altitude)), piexif.GPSIFD.GPSLatitudeRef: latDeg[3], piexif.GPSIFD.GPSLatitude: exivLat, piexif.GPSIFD.GPSLongitudeRef: lngDeg[3], piexif.GPSIFD.GPSLongitude: exivLng, } exifDict = {"GPS": gpsIfd} exifBytes = piexif.dump(exifDict) piexif.insert(exifBytes, fileName)
def _ed_ppx_exif(fle): img = Image.open(fle) # w, h = img.size exif_dict = piexif.load(img.info['exif']) # # exif_dict['Exif'][piexif.ImageIFD.XResolution] = (w, 1) # exif_dict['Exif'][piexif.ImageIFD.YResolution] = (h, 1) # multiply by 1.5 to get 35mm equiv apparently (based on googling) exif_dict['Exif'][piexif.ExifIFD.FocalLength]=(16, 30) exif_dict['Exif'][piexif.ExifIFD.FocalLengthIn35mmFilm]=(24,45) # if it was 30 as matej said # exif_dict['Exif'][piexif.ExifIFD.FocalLengthIn35mmFilm]=(24,45) # exif_dict["1st"][piexif.ImageIFD.XResolution] = (w, 1) # exif_dict["1st"][piexif.ImageIFD.YResolution] = (h, 1) # # exif_dict["1st"][piexif.ExifIFD.FocalLength]=(50, 5) # # exif_dict["1st"][piexif.ExifIFD.FocalLengthIn35mmFilm]=(75,10) exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, fle)
def download_album(account, password, main_folder_path): cookie_object = Cookie(account=account, password=password) for album_name, album_URL in Album(cookie_object=cookie_object).iterate_album_info(): print("Working on album {} ...".format(album_name)) album_folder_path = os.path.join(main_folder_path, album_name) os.makedirs(album_folder_path, exist_ok=True) for image_name, image_URL_tuple, image_time in Image(cookie_object=cookie_object, album_URL=album_URL).iterate_image_info(): image_file_path = os.path.join(album_folder_path, image_name) if os.path.isfile(image_file_path): continue print("Working on image {} ...".format(image_name)) for image_URL in image_URL_tuple: download_image(image_URL, image_file_path) if os.path.isfile(image_file_path): break if not os.path.isfile(image_file_path): print("Failed to download image {}!".format(image_name)) continue # Insert EXIF information datetime_object = datetime.strptime(image_time, "%a %b %d %H:%M:%S %Z %Y") exif_ifd = {piexif.ExifIFD.DateTimeOriginal: datetime_object.isoformat(" ")} exif_dict = {"Exif": exif_ifd} exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, image_file_path)
def AddGPS(latitude,longitude,image): strLat = str(latitude) strLon = str(longitude) #on calcul les N S E W if latitude>=0: latRef = 'N' else: latRef='S' if longitude>=0: lonRef = 'E' else : lonRef='W' #On supprime la virugle strLat = strLat.replace('.','') strLon = strLon.replace('.','') #On charge la photo print("---debut---"+str(image)) #on load les exif data exif_dict = piexif.load(image) #on ajoute les coordonnes exif_dict["GPS"][piexif.GPSIFD.GPSLatitudeRef] = latRef exif_dict["GPS"][piexif.GPSIFD.GPSLatitude] = [int(strLat),10000000] exif_dict["GPS"][piexif.GPSIFD.GPSLongitudeRef] = lonRef exif_dict["GPS"][piexif.GPSIFD.GPSLongitude] = [int(strLon), 10000000] exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, image) print("---fin---")
def to_thumbnail(path, max_size=500): img = cv2.imread(path, cv2.IMREAD_UNCHANGED) # Scale % = max_size / (max width or height) scale_percent = max_size / max(img.shape[0], img.shape[1]) width = int(img.shape[1] * scale_percent) height = int(img.shape[0] * scale_percent) dim = (width, height) # Preserve exif data, if any was_ok = False try: exif_bytes = piexif.dump(piexif.load(path)) was_ok = True except: print(path, " did not have exif data.") # Resize image resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA) # Save image cv2.imwrite(path, resized) # Transfer exif data if was_ok: piexif.insert(exif_bytes, path) return True
def write_exif(path): exif = {"0th": {}, "Exif": {}, "GPS": {}, "1st": {}} content = filename(args.content_img) style_names = map(lambda x: filename(x), args.style_imgs) styles = ",".join(style_names) keywords = "{0},{1}".format(content, styles) comment = "max_size={0},max_iterations={1},init_img_type={2},content_weight={3},style_weight={4},tv_weight={5},temporal_weight={6},content_loss_function={7}, color_convert_type={8},pooling_type={9},optimizer={10},learning_rate={11},model={12}".format( args.max_size, args.max_iterations, args.init_img_type, args.content_weight, args.style_weight, args.tv_weight, args.temporal_weight, args.content_loss_function, args.color_convert_type, args.pooling_type, args.optimizer, args.learning_rate, args.model_weights) exif["0th"][piexif.ImageIFD.XPAuthor] = bytearray( "Sebastian Betzin".encode("utf-16-le")) exif["0th"][piexif.ImageIFD.XPKeywords] = bytearray( keywords.encode("utf-16-le")) exif["0th"][piexif.ImageIFD.XPTitle] = bytearray( content.encode("utf-16-le")) exif["0th"][piexif.ImageIFD.XPSubject] = bytearray( styles.encode("utf-16-le")) exif["0th"][piexif.ImageIFD.XPComment] = bytearray( comment.encode("utf-16-le")) exif_bytes = piexif.dump(exif) piexif.insert(exif_bytes, path)
def __set_gps_location(self, gpsTime): """Adds GPS position as EXIF metadata Keyword arguments: file_name -- image file lat -- latitude (as float) lng -- longitude (as float) altitude -- altitude (as float) """ lat_deg = self.__to_deg(self.latitude, ["S", "N"]) lng_deg = self.__to_deg(self.longitude, ["W", "E"]) print(self.latitude) print(self.longitude) exiv_lat = (self.__change_to_rational(lat_deg[0]), self.__change_to_rational(lat_deg[1]), self.__change_to_rational(lat_deg[2])) exiv_lng = (self.__change_to_rational(lng_deg[0]), self.__change_to_rational(lng_deg[1]), self.__change_to_rational(lng_deg[2])) gps_ifd = { piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0), piexif.GPSIFD.GPSAltitudeRef: 0, piexif.GPSIFD.GPSAltitude: self.__change_to_rational(round(self.altitude)), piexif.GPSIFD.GPSLatitudeRef: lat_deg[3], piexif.GPSIFD.GPSLatitude: exiv_lat, piexif.GPSIFD.GPSLongitudeRef: lng_deg[3], piexif.GPSIFD.GPSLongitude: exiv_lng, } exif_dict = {"GPS": gps_ifd} exif_bytes = piexif.dump(exif_dict) # BUG here in simulation maybe working in real life. piexif.insert(exif_bytes, self.file_name)
def shoot_image_using_jpeg(self): CameraControl.camera.resolution = self.params['max_resol'] CameraControl.image_stream = BytesIO() temp_jpeg = '/tmp/jpeg_caputre.tmp' self.shutterSound() CameraControl.camera.capture( temp_jpeg, 'jpeg', quality=CameraControl.params['jpeg_quality']) # # Add Exif # orientation # exif_dict = piexif.load(temp_jpeg) exif_dict["0th"][ piexif.ImageIFD.Orientation] = CameraControl.params['Orientation'] #piexif.remove(temp_jpeg) exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, temp_jpeg) # # Read file into BytesIO stream # f = open(temp_jpeg, 'rb') image_stream = BytesIO() CameraControl.image_stream.write(f.read()) f.close() os.remove(temp_jpeg)
def upload_image(): if request.method == 'POST': img_data = request.files['src'] filename = request.form['date'] location = request.form['location'] full_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) img_data.save(full_path) # resize the image to fit from PIL import Image import piexif basewidth = 480 img = Image.open(full_path) wpercent = (basewidth / float(img.size[0])) hsize = int((float(img.size[1]) * float(wpercent))) img = img.resize((basewidth, hsize), Image.ANTIALIAS) img.save(full_path) # update metadata to store location piexif.remove(full_path) exif_dict = piexif.load(full_path) exif_dict['Exif'] = {piexif.ExifIFD.UserComment: str(location)} exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, full_path) return 'SUCCESS'
def save_seq_num(img,img_name,seq): key = get_config('tags')[2] value = str(seq) tags = get_meta_dict(img) tags[key] = value debug('new tag dict to insert',tags) exif_bytes = piexif.dump(tags) piexif.insert(exif_bytes, img_name)
def test_insert_m(self): """'insert' on memory. """ exif_dict = {"0th":ZEROTH_IFD, "Exif":EXIF_IFD, "GPS":GPS_IFD} exif_bytes = piexif.dump(exif_dict) o = io.BytesIO() piexif.insert(exif_bytes, I1, o) self.assertEqual(o.getvalue()[0:2], b"\xff\xd8") exif = load_exif_by_PIL(o)
def insert_sample(): zeroth_ifd = {282: (96, 1), 283: (96, 1), 296: 2, 305: 'piexif'} exif_bytes = piexif.dump({"0th":zeroth_ifd}) piexif.insert(exif_bytes, "remove_sample.jpg", "insert_sample.jpg")
def test_insert_fail1(self): with open(INPUT_FILE1, "rb") as f: data = f.read() with open("insert.jpg", "wb+") as f: f.write(data) exif_dict = {"0th":ZEROTH_IFD, "Exif":EXIF_IFD, "GPS":GPS_IFD} exif_bytes = piexif.dump(exif_dict) with self.assertRaises(ValueError): piexif.insert(exif_bytes, INPUT_FILE_TIF) os.remove("insert.jpg")
def writeExifUserComment(imagePath,userCommentAsDict): # read in the exif data, add the user comment as json, and write it exif_dict = piexif.load(imagePath) # convert the jason to proper encoding user_comment = piexif.helper.UserComment.dump(json.dumps(userCommentAsDict)) # pop it into the exif_dict exif_dict["Exif"][piexif.ExifIFD.UserComment] = user_comment # get the exif as bytes exif_bytes = piexif.dump(exif_dict) # insert the modified exif_bytes piexif.insert(exif_bytes, imagePath)
def download_photos(): ssl._create_default_https_context = ssl._create_unverified_context #Prep the download folder folder = 'photos/' if not os.path.exists(folder): os.makedirs(folder) print("Saving photos to " + folder) #Download the photos with open('tagged.json') as json_file: data = json.load(json_file) for i,d in enumerate(data['tagged']): if d['media_type'] == 'image': #Save new file if d['fb_date'] == "Today": filename_date = datetime.today().strftime('%Y-%m-%d') elif d['fb_date'] == "Yesterday": filename_date = datetime.today() - timedelta(days=1) filename_date = filename_date.strftime('%Y-%m-%d') else: filename_date = parse(d['fb_date']).strftime("%Y-%m-%d") img_id = d['media_url'].split('_')[1] new_filename = folder + filename_date + '_' + img_id + '.jpg' if os.path.exists(new_filename): print("Already Exists (Skipping): %s" % (new_filename)) else: delay = 1 while True: try: print("Downloading " + d['media_url']) img_file = wget.download(d['media_url'], new_filename, False) break except (TimeoutError, urllib.error.URLError) as e: print("Sleeping for {} seconds".format(delay)) time.sleep(delay) delay *= 2 #Update EXIF Date Created exif_dict = piexif.load(img_file) if d['fb_date'] == "Today": exif_date = datetime.today().strftime("%Y:%m:%d %H:%M:%S") elif d['fb_date'] == "Yesterday": exif_date = datetime.today() - timedelta(days=1) exif_date = exif_date.strftime("%Y:%m:%d %H:%M:%S") else: exif_date = parse(d['fb_date']).strftime("%Y:%m:%d %H:%M:%S") img_desc = d['fb_caption'] + '\n' + d['fb_tags'] + '\n' + d['fb_url'].split("&")[0] exif_dict['Exif'][piexif.ExifIFD.DateTimeOriginal] = exif_date exif_dict['0th'][piexif.ImageIFD.Copyright] = (d['user_name'] + ' (' + d['user_url']) + ')' exif_dict['0th'][piexif.ImageIFD.ImageDescription] = img_desc.encode('utf-8') piexif.insert(piexif.dump(exif_dict), img_file) print(str(i+1) + ') Added '+ new_filename)
def set_photo_exif(path, date): """Set EXIF date on a photo, do nothing if there is an error""" try: exif_dict = piexif.load(path) exif_dict.get("1st")[306] = date exif_dict.get("Exif")[36867] = date exif_dict.get("Exif")[36868] = date exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, path) except (ValueError, InvalidImageDataError): logger = setup_logger() logger.debug("Error setting EXIF data for %s", path) return
def add_exif(raw_file,outfile): f = open(raw_file, 'rb') tags = exifread.process_file(f) exif_ifd = {piexif.ExifIFD.DateTimeOriginal: str(tags['EXIF DateTimeOriginal'])} # create nested dic exif_dict = {"Exif":exif_ifd} # turn dict into format that can be sent as exif exif_dic_bytes = piexif.dump(exif_dict) # write exif into jpeg file piexif.insert(exif_dic_bytes, outfile)
def write(self, filename=None): """Save exif data to file.""" if filename is None: filename = self._filename exif_bytes = piexif.dump(self._ef) with open(self._filename, "rb") as fin: img = fin.read() try: piexif.insert(exif_bytes, img, filename) except IOError: type, value, traceback = sys.exc_info() print >> sys.stderr, "Error saving file:", value
def test_insert(self): exif_dict = {"0th":ZEROTH_IFD, "Exif":EXIF_IFD, "GPS":GPS_IFD} exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, INPUT_FILE1, "insert.jpg") exif = load_exif_by_PIL("insert.jpg") piexif.insert(exif_bytes, NOEXIF_FILE, "insert.jpg") with self.assertRaises(ValueError): piexif.insert(b"dummy", io.BytesIO()) piexif.insert(exif_bytes, "insert.jpg") os.remove("insert.jpg")
def remove_gps_folder(folder, new_folder=None, original=True, status_print=False): """Remove GPS from EXIF of all jpgs in a folder. folder: Location of original folder. new_folder: Location of folder for modified images. Optional. original: Flag indicating whether to use original image data. Optional. Default is True. Alternative would be to replace EXIF of existing images with matching filenames. status_print: Flag indicating whether to print current progress. Optional. Default is False. """ folder = _check_path(folder) if new_folder == None: new_folder = folder elif not os.path.exists(new_folder): os.mkdir(new_folder) photos = os.listdir(folder) photos.sort() for photo in photos: if os.path.isfile(os.path.join(folder, photo)): if (os.path.splitext(photo)[1]).lower() == ".jpg": old_file = os.path.join(folder, photo) new_file = os.path.join(new_folder, photo) gps = None if original == False: (exif_bytes, gps) = remove_gps_exif(old_file) piexif.insert(exif_bytes, new_file) else: gps = remove_gps_photo(old_file, new_file) if status_print == True: if gps: print photo else: print gps print photo + " - Nope!"
def test_roundtrip_files(self): files = glob.glob(os.path.join("tests", "images", "r_*.jpg")) for input_file in files: print(input_file) exif = piexif.load(input_file) exif_bytes = piexif.dump(exif) o = io.BytesIO() piexif.insert(exif_bytes, input_file, o) e = piexif.load(o.getvalue()) t = e.pop("thumbnail") thumbnail = exif.pop("thumbnail") if t is not None: if not (b"\xe0" <= thumbnail[3:4] <= b"\xef"): self.assertEqual(t, thumbnail) else: print("Given JPEG doesn't follow exif thumbnail standard. " "APPn segments in thumbnail should be removed, " "whereas thumbnail JPEG has it. \n: " + input_file) exif["1st"].pop(513) e["1st"].pop(513) exif["1st"].pop(514) e["1st"].pop(514) for ifd in e: if ifd == "0th": if ImageIFD.ExifTag in exif["0th"]: exif["0th"].pop(ImageIFD.ExifTag) e["0th"].pop(ImageIFD.ExifTag) if ImageIFD.GPSTag in exif["0th"]: exif["0th"].pop(ImageIFD.GPSTag) e["0th"].pop(ImageIFD.GPSTag) elif ifd == "Exif": if ExifIFD.InteroperabilityTag in exif["Exif"]: exif["Exif"].pop(ExifIFD.InteroperabilityTag) e["Exif"].pop(ExifIFD.InteroperabilityTag) for key in exif[ifd]: self.assertEqual(exif[ifd][key], e[ifd][key]) print(" - pass")
def _update(self): packed = piexif.dump(self.exif) piexif.insert(packed, self.filename)
def get_file_from_json_struct(data_obj_json_struct, output_dir, fn, thumbnail_size, add_percent=12.5): """ Get and crop a file using data present in an EoL json response, which includes object ID, crop info, etc Return the rights & license, or None if something failed. Directories are created as necessary """ #NB: image_cols = ['dataObjectVersionID','eolMediaURL','vettedStatus','dataRating','crop_x', 'crop_y', 'crop_width'] #note that crop_width is in percent **** import shutil from subprocess import call import urllib.request import urllib.error import piexif CONVERT = shutil.which('convert') #needed in windows, to get the correct 'convert' command d=data_obj_json_struct fn = str(fn) os.umask(0o002) #set group write so that the normal login has same rights as the web server os.makedirs(output_dir, exist_ok=True) if 'eolMediaURL' not in d: logger.error("'eolMediaURL' must be present in data object {}.".format(d)) return None try: output_fn = os.path.join(output_dir, fn) image_orig = output_fn + '_orig.jpg' image_intermediate = output_fn + '_tmp.jpg' image_final = output_fn + '.jpg' logger.info("Downloading {} to {}.".format(d['eolMediaURL'], image_orig)) try: urllib.request.urlretrieve(d['eolMediaURL'], image_orig) os.chmod(image_orig, 0o664) #allow both the webserver and the web2py user (both in the same group) to overwrite these files except urllib.error.HTTPError as err: if err.code == 404: logger.warning("404: File '{0}' missing for data object {1} @ http://eol.org/data_objects/{1}".format(d['eolMediaURL'], image_orig)) return None else: raise #calculate fractions as proportion of square thumbnail try: initial_thumb_px = float(d['crop_width']) crop_top_fraction = float(d['crop_y'])/initial_thumb_px crop_bottom_fraction = (float(d['height']) - float(d['crop_y']) - initial_thumb_px)/initial_thumb_px crop_left_fraction = float(d['crop_x'])/initial_thumb_px crop_right_fraction = (float(d['width']) - float(d['crop_x']) - initial_thumb_px)/initial_thumb_px min_crop_fraction = min(crop_top_fraction, crop_bottom_fraction, crop_left_fraction, crop_right_fraction) if min_crop_fraction < 0: #the crop is right against the corner, and we cannot make it bigger top = str(int(round(float(d['crop_y'])))) left = str(int(round(float(d['crop_x'])))) size = str(int(round(float(d['crop_width'])))) if add_percent>0: logger.debug("Cannot expand crop for data object {} by {}%: image is against the edge.".format(fn, add_percent)) else: if min_crop_fraction > add_percent/100.0: min_crop_fraction = add_percent/100.0 else: if add_percent>0: logger.debug("NOTICE: Cannot expand crop for data object {} by {}%: borders are not large enough, so using {}%.".format(fn, add_percent, min_crop_fraction*100)) min_crop_pixels = min_crop_fraction * initial_thumb_px top = str(int(round(float(d['crop_y']) - min_crop_pixels))) left = str(int(round(float(d['crop_x']) - min_crop_pixels))) size = str(int(round(initial_thumb_px + 2*min_crop_pixels))) logger.log(logging.EXTREME_DEBUG, "crop info: {}...{}, {}".format(initial_thumb_px, 2*min_crop_pixels, size)) cmd = [CONVERT, image_orig, '-crop', size+'x'+size+'+'+left+'+'+top, '+repage', '-resize', str(thumbnail_size)+'x'+str(thumbnail_size), image_intermediate ] logger.debug("Custom crop: {}.".format(" ".join(cmd))) except KeyError: #hasn't got crop info: use default cmd = [CONVERT, image_orig, '-gravity', 'Center', '-resize', str(thumbnail_size)+'x'+str(thumbnail_size)+'^', "-extent", str(thumbnail_size)+'x'+str(thumbnail_size), image_intermediate ] logger.debug("Default crop: {}.".format(" ".join(cmd))) call(cmd) r, l = get_credit(d, fn) copyright_str = ' / '.join([r, l]) rating = convert_rating(d['dataRating']) #EXIF 'Rating' is 16bit unsigned, i.e. 0-65535. EoL ratings are 0-5 floating point, so for ease of mapping we multiply EOL ratings by 10,000 to get ratings from 0-50,000 #call(['exiftool', '-q', '-codedcharacterset=utf8', '-IPTC:Contact='+'http://eol.org/data_objects/'+fn, '-IPTC:Credit='+r, '-IPTC:CopyrightNotice='+l, '-overwrite_original', '-m', image_orig]) piexif.insert(piexif.dump({"0th":{piexif.ImageIFD.Copyright:copyright_str.encode("utf8"), piexif.ImageIFD.Rating:rating}, "Exif":{}}), image_intermediate) logger.info("Downloaded with rating {} and cropped into {}".format(rating, image_intermediate)) except OSError as e: logger.error("Cannot call 'convert' properly: {}\n Have you installed Imagemagick?".format(e)) return None try: os.remove(image_orig) os.chmod(image_intermediate, 0o664) #allow both www & web2py to overwrite, etc if os.path.exists(image_final) and filecmp.cmp(image_intermediate, image_final, shallow=False): logger.info("Deleted large original, but cropped version is identical to old image ({}), so not replacing".format(image_final)) os.remove(image_intermediate) else: os.replace(image_intermediate, image_final) logger.info("Deleted large original and moved cropped image from {} into {}".format(image_intermediate, image_final)) except OSError as e: logger.warning("Could not remove the original downloaded file, or move the new file to its final place: {} \nPerhaps EoL has a problem.".format(e)) return None return (r,l)
def main(): opt_parser = optparse.OptionParser() opt_parser.add_option( '-l', '--locaction', dest='loc', help='Location to set') options, args = opt_parser.parse_args() if options.loc: parts = options.loc.split(',') if len(parts) < 2 or len(parts) > 3: print 'location must be 2 or 3 parts' return specified_gps_info = GPSInfo( float(parts[0].strip()), float(parts[1].strip()), float(parts[2].strip()) if len(parts) == 3 else None) else: specified_gps_info = None if not specified_gps_info: time_maps = {} for fn in args: if fn.endswith('.kml'): kml = ET.parse(fn) track = kml.find('.//gx:Track', KMLNS) when = coord = None for e in track.getchildren(): if e.tag.endswith('when'): when = parser.parse(e.text) elif e.tag.endswith('coord'): coord = e.text time_maps[when] = coord timed_locs = sorted(time_maps.iteritems()) default_tz = None tzs = set(x.tzinfo.utcoffset(None) for x, _ in timed_locs) if len(tzs) == 1: default_tz = timed_locs[0][0].tzinfo for fn in args: if not fn.endswith('.kml'): try: exif = piexif.load(fn) except: print 'Fail to load exif from %s' % fn continue if specified_gps_info: gps_info = specified_gps_info else: time = exif['Exif'][piexif.ExifIFD.DateTimeOriginal] if not time: print 'DateTimeOriginal not found in ' + fn continue dp, tp = time.split(' ', 2) time = ' '.join([dp.replace(':', '/'), tp]); t = parser.parse(time) if not t.tzinfo: t = t.replace(tzinfo=default_tz) p = bisect.bisect(timed_locs, (t, None)) if p == 0: g = 0 elif p == len(timed_locs): g = len(timed_locs) - 1 else: dt0 = t - timed_locs[p - 1][0] dt1 = timed_locs[p][0] - t if dt0 < dt1: g = p - 1 else: g = p gps_info = kml_loc_to_gpsinfo(timed_locs[g][1]) lonref, lon = to_gps_latlon(gps_info.longitude, ('E', 'W')) exif['GPS'][piexif.GPSIFD.GPSLongitudeRef] = lonref exif['GPS'][piexif.GPSIFD.GPSLongitude] = lon latref, lat = to_gps_latlon(gps_info.latitude, ('N', 'S')) exif['GPS'][piexif.GPSIFD.GPSLatitudeRef] = latref exif['GPS'][piexif.GPSIFD.GPSLatitude] = lat if gps_info.altitude: altref, alt = to_gps_alt(gps_info.altitude) exif['GPS'][piexif.GPSIFD.GPSAltitudeRef] = altref exif['GPS'][piexif.GPSIFD.GPSAltitude] = alt if not specified_gps_info: u = timed_locs[g][0].utctimetuple() exif['GPS'][piexif.GPSIFD.GPSTimeStamp] = ( (u.tm_hour, 0), (u.tm_min, 0), (u.tm_sec, 0)) exif['GPS'][piexif.GPSIFD.GPSDateStamp] = '%04d:%02d:%02d' % ( u.tm_year, u.tm_mon, u.tm_mday) piexif.insert(piexif.dump(exif), fn) if specified_gps_info: print 'Tagged %s' % fn else: dt = timed_locs[g][0] - t print 'Tagged %s (%s) with %d seconds certainty at %s, %s' % ( fn, time, abs(dt.total_seconds()), gps_info.latitude, gps_info.longitude)
def writeExifToFile(exifDict, fileAddress): exifBytes = piexif.dump(exifDict) piexif.insert(exifBytes, fileAddress)
def test_insert_fail2(self): exif_dict = {"0th":ZEROTH_IFD, "Exif":EXIF_IFD, "GPS":GPS_IFD} exif_bytes = piexif.dump(exif_dict) with self.assertRaises(ValueError): piexif.insert(exif_bytes, I1, False)
def getExif(fileName): vyrez = Image.open(fileName) exifDict = piexif.load(vyrez.info["exif"]) print(exifDict) return exifDict exifDict=getExif('vyrez.jpg') oldThumb = exifDict["thumbnail"] #I chose to hide the secret text message in the field "Software" exifDict["1st"][piexif.ImageIFD.Software] = "-------------Tajna zprava---------------------" exifDict["thumbnail"] = ImageDump("wolf.jpg") exifBytes = piexif.dump(exifDict) piexif.insert(exifBytes, "vyrez.jpg") exifDict2 = getExif('vyrez.jpg') #print text message stored in exif print(exifDict2["1st"][piexif.ImageIFD.Software]) #now remove the meta image and secret message: exifDict2["thumbnail"] = oldThumb exifDict2["1st"][piexif.ImageIFD.Software] = "" exifBytes2 = piexif.dump(exifDict2) piexif.insert(exifBytes2, "vyrez.jpg") exifDict3 = getExif('vyrez.jpg') #print text message stored in exif print(exifDict3["1st"][piexif.ImageIFD.Software])
print(camera_capture.data['alt'][offsets[offset]]) lat = camera_capture.data['lat'][offsets[offset]] lng = camera_capture.data['lon'][offsets[offset]] altitude = camera_capture.data['alt'][offsets[offset]] lat_deg = to_deg(lat, ["S", "N"]) lng_deg = to_deg(lng, ["W", "E"]) exiv_lat = (change_to_rational(lat_deg[0]), change_to_rational(lat_deg[1]), change_to_rational(lat_deg[2])) exiv_lng = (change_to_rational(lng_deg[0]), change_to_rational(lng_deg[1]), change_to_rational(lng_deg[2])) gps_ifd = { piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0), piexif.GPSIFD.GPSAltitudeRef: 0, piexif.GPSIFD.GPSAltitude: change_to_rational(round(altitude)), piexif.GPSIFD.GPSLatitudeRef: lat_deg[3], piexif.GPSIFD.GPSLatitude: exiv_lat, piexif.GPSIFD.GPSLongitudeRef: lng_deg[3], piexif.GPSIFD.GPSLongitude: exiv_lng, } exif_dict["GPS"] = gps_ifd exif_bytes = piexif.dump(exif_dict) piexif.insert(exif_bytes, f) else: print "Could not georeference" print "Done"
def write_gps(filename, lat, longit, altitude): #lat and long are decimals gps = {} #create array #Altitude if altitude<0: gps[piexif.GPSIFD.GPSAltitudeRef] = 1; #Below see level else: gps[piexif.GPSIFD.GPSAltitudeRef] = 0; #Above see level gps[piexif.GPSIFD.GPSAltitude]= (int(abs(altitude)*100),100) #Latitude if lat<0: gps[piexif.GPSIFD.GPSLatitudeRef] = "S" else: gps[piexif.GPSIFD.GPSLatitudeRef] = "N" latd,latm,lats = ExifWriter._decdeg2dms(lat) gps[piexif.GPSIFD.GPSLatitude] = [(latd,1),(latm,1),(lats*100,100)]; #Longitude if longit<0: gps[piexif.GPSIFD.GPSLongitudeRef] = "W" else: gps[piexif.GPSIFD.GPSLongitudeRef] = "E" longd,longm,longs = ExifWriter._decdeg2dms(longit) gps[piexif.GPSIFD.GPSLongitude] = [(longd,1),(longm,1),(longs*100,100)]; exifdict = piexif.load(filename) exifdict["GPS"] = gps exif_bytes = piexif.dump(exifdict) piexif.insert(exif_bytes, filename) exifdict = piexif.load(filename)