def test_thumbnail(self): e1 = pyxif.load(INPUT_FILE1) pyxif.thumbnail(INPUT_FILE1, "thumbnail.jpg", (50, 50)) e2 = pyxif.load("thumbnail.jpg") self.assertEqual(e1, e2) try: i = Image.open("thumbnail.jpg") i._getexif() except: self.fail("'thumbnail' generated wrong file") finally: i.close()
def test_transplant2(self): """To use on server. Passes binary data to input, and passes io.BytesIO instance to output """ o = io.BytesIO() pyxif.transplant(I1, I2, o) self.assertEqual(pyxif.load(I1), pyxif.load(o.getvalue())) try: i = Image.open(o) i._getexif() except: self.fail("'transplant' generated wrong file") finally: i.close()
def load_bright(filename): """ Load luminosity of the shot scene, according to te image metadata :param filename: name/path of the file :return: float, level of brightness """ try: zeroth_dict, exif_dict, gps_dict = pyxif.load(filename) num,denom = exif_dict[pyxif.PhotoGroup.BrightnessValue][1] brightness = num/denom return brightness except KeyError: try: f_number = exif_dict[pyxif.PhotoGroup.FNumber][1][0]/exif_dict[pyxif.PhotoGroup.FNumber][1][0] ISO_speed = exif_dict[pyxif.PhotoGroup.ISOSpeedRatings][1] expo_time = exif_dict[pyxif.PhotoGroup.ExposureTime][1][0] / exif_dict[pyxif.PhotoGroup.ExposureTime][1][0] brightness = np.log2(f_number**2) + np.log2(1/expo_time) - np.log2(2**(-7/4)*ISO_speed) return brightness except KeyError: print("WARNING No brightness data for file " + filename) print("Check if your exif data contains a 'BrightnessValue' tag ") return None except FileNotFoundError: print("WARNING Could not find file " + filename ) return None
def test_load2(self): """To use on server. Passes binary data to input. """ zeroth_dict, exif_dict, gps_dict = pyxif.load(I1) self.assertEqual(zeroth_dict[272][1], "QV-R51 ") self.assertEqual(zeroth_dict[296][1], 2) self.assertEqual(zeroth_dict[282][1], (72, 1))
def test_thumbnail2(self): """To use on server. Passes binary data to input, and passes io.BytesIO instance to output """ o = io.BytesIO() pyxif.thumbnail(I1, o, (50, 50)) e1 = pyxif.load(I1)[0] e2 = pyxif.load(o.getvalue())[0] self.assertEqual(e1, e2) o.seek(0) try: i = Image.open(o) i._getexif() except: self.fail("'thumbnail' generated wrong file") finally: i.close()
def test_transplant(self): pyxif.transplant(INPUT_FILE1, INPUT_FILE2, "transplant.jpg") exif_src = pyxif.load(INPUT_FILE1) img_src = pyxif.load(INPUT_FILE2) generated = pyxif.load("transplant.jpg") self.assertEqual(exif_src, generated) self.assertNotEqual(img_src, generated) try: i = Image.open("transplant.jpg") i._getexif() except: self.fail("'transplant' generated wrong file") finally: i.close() with self.assertRaises(ValueError): pyxif.transplant(NOEXIF_FILE, INPUT_FILE2, "foo.jpg")
def insert(cls, filepath, check_for_existing=True): if check_for_existing: (pic, created) = cls.objects.get_or_create(filepath=filepath) else: pic = cls() try: # Load image, exif, and file information im = Image.open(filepath) dummy, exif_dict, dummy = pyxif.load(filepath) filestat = os.stat(filepath) # Image stats for calculations width = 2048 height = 1536 top_row = 36 hd_height = int(round((width * 1080) / 1920)) bottom_row = hd_height + top_row # File stats pic.filepath = filepath pic.filename = os.path.basename(filepath) pic.size = filestat.st_size # Timestamp (UTC) 2014-06-16-00-00-02.jpg timestamp = datetime.strptime( pic.filename.split('.')[0], '%Y-%m-%d-%H-%M-%S') pic.timestamp = timezone.make_aware(timestamp, utc) # Exif Info pic.fstop, pic.exposure = get_fstop_exposure(exif_dict) # Color info (Clouds only) imclouds = im.crop((0, top_row, width, bottom_row)) cloudstats = ImageStat.Stat(imclouds) exc = cloudstats.extrema pic.center_color = rgb_to_int( imclouds.getpixel( (int(round(width / 2.0)), int(round(hd_height / 2.0))))) pic.mean_color = rgb_to_int(cloudstats.mean) pic.median_color = rgb_to_int(cloudstats.median) pic.stddev_red = int(round(cloudstats.stddev[0])) pic.stddev_green = int(round(cloudstats.stddev[1])) pic.stddev_blue = int(round(cloudstats.stddev[2])) pic.min_color = rgb_to_int((exc[0][0], exc[1][0], exc[2][0])) pic.max_color = rgb_to_int((exc[0][1], exc[1][1], exc[2][1])) pic.valid = True if im.size != (2048, 1536): pic.valid = False except: pic.valid = False pic.save() return pic
def test_remove(self): pyxif.remove(INPUT_FILE1, "remove.jpg") exif = pyxif.load("remove.jpg")[0] self.assertEqual(exif, {}) try: i = Image.open("remove.jpg") i._getexif() except: self.fail("'remove' generated wrong file") finally: i.close()
def insert(cls, filepath, check_for_existing=True): if check_for_existing: (pic, created) = cls.objects.get_or_create(filepath=filepath) else: pic = cls() try: # Load image, exif, and file information im = Image.open(filepath) dummy, exif_dict, dummy = pyxif.load(filepath) filestat = os.stat(filepath) # Image stats for calculations width = 2048 height = 1536 top_row = 36 hd_height = int(round((width * 1080) / 1920)) bottom_row = hd_height + top_row # File stats pic.filepath = filepath pic.filename = os.path.basename(filepath) pic.size = filestat.st_size # Timestamp (UTC) 2014-06-16-00-00-02.jpg timestamp = datetime.strptime(pic.filename.split('.')[0], '%Y-%m-%d-%H-%M-%S') pic.timestamp = timezone.make_aware(timestamp, utc) # Exif Info pic.fstop, pic.exposure = get_fstop_exposure(exif_dict) # Color info (Clouds only) imclouds = im.crop((0,top_row,width,bottom_row)) cloudstats = ImageStat.Stat(imclouds) exc = cloudstats.extrema pic.center_color = rgb_to_int(imclouds.getpixel((int(round(width / 2.0)),int(round(hd_height / 2.0))))) pic.mean_color = rgb_to_int(cloudstats.mean) pic.median_color = rgb_to_int(cloudstats.median) pic.stddev_red = int(round(cloudstats.stddev[0])) pic.stddev_green = int(round(cloudstats.stddev[1])) pic.stddev_blue = int(round(cloudstats.stddev[2])) pic.min_color = rgb_to_int((exc[0][0], exc[1][0], exc[2][0])) pic.max_color = rgb_to_int((exc[0][1], exc[1][1], exc[2][1])) pic.valid = True if im.size != (2048,1536): pic.valid = False except: pic.valid = False pic.save() return pic
def test_load(self): zeroth_dict, exif_dict, gps_dict = pyxif.load(INPUT_FILE1) exif_dict.pop(41728) # value type is UNDEFINED but PIL returns int i = Image.open(INPUT_FILE1) e = i._getexif() i.close() for key in sorted(zeroth_dict): if key in e: self.assertEqual(zeroth_dict[key][1], e[key]) for key in sorted(exif_dict): if key in e: self.assertEqual(exif_dict[key][1], e[key]) for key in sorted(gps_dict): if key in e: self.assertEqual(gps_dict[key][1], e[key])
def test_remove2(self): """To use on server. Passes binary data to input, and passes io.BytesIO instance to output """ o = io.BytesIO() with self.assertRaises(ValueError): pyxif.remove(I1) pyxif.remove(I1, o) exif = pyxif.load(o.getvalue()) self.assertEqual(exif, ({}, {}, {})) try: i = Image.open(o) i._getexif() except: self.fail("'remove' generated wrong file") finally: i.close()
def load_date(filename): """ Load date of the shot, according to te image metadata :param filename: name/path of the file :return: datetime format """ try: zeroth_dict, exif_dict, gps_dict = pyxif.load(filename) date,time=exif_dict[pyxif.PhotoGroup.DateTimeOriginal][1].split(" ") year, month,day = date.split(":") hour,minute,sec = time.split(":") dateimage= datetime(int(year), int(month), int(day), int(hour), int(minute) ,int(sec)) return dateimage except KeyError: print("WARNING No date for file " + filename) return None except FileNotFoundError: print("WARNING Could not find file " + filename ) return None
def load_date(filename, date_in_fname=False, date_pattern=None): """ Load date of the shot, according to te image metadata :param filename: name/path of the file :param date_in_fname: Boolean for using filename as date or not :param date_pattern: a list of pattern using strptime formating system, e.g. ['cam1_%Y%m%d_%H%M.JPG','cam2_%Y%m%d_%H%M.JPG']. :return: datetime format """ try: if date_in_fname: if date_pattern is None: print( 'ERROR: if using filename for date, date_pattern must be given' ) return else: if date_pattern.__len__() > 1: for pat in date_pattern: try: dateimage = datetime.strptime( filename.split('/')[-1], pat) except: continue else: dateimage = datetime.strptime( filename.split('/')[-1], date_pattern) else: zeroth_dict, exif_dict, gps_dict = pyxif.load(filename) date, time = exif_dict[pyxif.PhotoGroup.DateTimeOriginal][1].split( " ") year, month, day = date.split(":") hour, minute, sec = time.split(":") dateimage = datetime(int(year), int(month), int(day), int(hour), int(minute), int(sec)) return dateimage except KeyError: print("WARNING No date for file " + filename) return None except FileNotFoundError: print("WARNING Could not find file " + filename) return None
def load_bright(filename): """ Load luminosity of the shot scene, according to te image metadata :param filename: name/path of the file :return: float, level of brightness TODO: Add a method to estimate BrightnessValue of image if the field is not available from picture EXIF. """ try: zeroth_dict, exif_dict, gps_dict = pyxif.load(filename) num, denom = exif_dict[pyxif.PhotoGroup.BrightnessValue][1] brightness = num / denom return brightness except KeyError: print("WARNING No brightness data for file " + filename) print("Check if your exif data contains a 'BrightnessValue' tag ") return None except FileNotFoundError: print("WARNING Could not find file " + filename) return None
def load_sample(input_file): zeroth_dict, exif_dict, gps_dict = pyxif.load(input_file) print("******************************") print("0th IFD: {0}".format(len(zeroth_dict))) for key in sorted(zeroth_dict): print(key, zeroth_dict[key]) print("\nEXIF IFD: {0}".format(len(exif_dict))) for key in sorted(exif_dict): if isinstance(exif_dict[key][1], (str, bytes)) and len(exif_dict[key][1]) > 30: print(key, exif_dict[key][0], exif_dict[key][1][:10] + b"...", len(exif_dict[key][1])) else: print(key, exif_dict[key]) print("\nGPS IFD: {0}".format(len(gps_dict))) for key in sorted(gps_dict): if isinstance(gps_dict[key][1], (str, bytes)) and len(gps_dict[key][1]) > 30: print(key, gps_dict[key][0][:10], gps_dict[key][1][:10] + b"...", len(exif_dict[key][1])) else: print(key, gps_dict[key])
def dump_sample(input_file, output_file): zeroth_ifd = {pyxif.ImageGroup.Make: "fooooooooooooo", pyxif.ImageGroup.XResolution: (96, 1), pyxif.ImageGroup.YResolution: (96, 1), pyxif.ImageGroup.Software: "paint.net 4.0.3", } exif_ifd = {pyxif.PhotoGroup.ExifVersion: "0111", pyxif.PhotoGroup.DateTimeOriginal: "1999:09:99 99:99:99", pyxif.PhotoGroup.CameraOwnerName: "Mr. John Doe", } gps_ifd = {pyxif.GPSInfoGroup.GPSDateStamp: "1999:99:99", pyxif.GPSInfoGroup.GPSDifferential: 90, } exif_bytes = pyxif.dump(zeroth_ifd=zeroth_ifd, exif_ifd=exif_ifd, gps_ifd=gps_ifd) im = Image.open(input_file) im.thumbnail((100, 100), Image.ANTIALIAS) im.save(output_file, exif=exif_bytes) z, e, g = pyxif.load(output_file) print(z, e, g)