def test_write_new_struct_in_array(self): filename = pkg_resources.resource_filename(__name__, "samples/test1.xmp") with open(filename, 'r') as fptr: strbuffer = fptr.read() xmp = XMPMeta() xmp.parse_from_str(strbuffer) prefix = xmp.get_prefix_for_namespace(NS_DC) xmp.append_array_item(NS_DC, prefix + 'creator', None, prop_value_is_struct=True) xmp.set_property(NS_DC, prefix + 'creator[2]/' + prefix + 'TestProp', '100') self.assertTrue(xmp.does_property_exist(NS_DC, prefix + 'creator[2]')) prop = xmp.get_property(NS_DC, prefix + 'creator[2]/%sTestProp' % prefix) self.assertEqual(prop, '100') xpath = prefix + 'creator' xmp.set_array_item(NS_DC, xpath, 3, None, prop_value_is_struct=True) xpath += '[3]/%sTestProp' % prefix xmp.set_property(NS_DC, xpath, '200') self.assertTrue(xmp.does_property_exist(NS_DC, xpath)) prop = xmp.get_property(NS_DC, xpath) self.assertEqual(prop, '200') xpath = prefix + 'TestStruct/' + prefix + 'TestValue' xmp.set_property(NS_DC, xpath, '300') self.assertTrue(xmp.does_property_exist(NS_DC, xpath)) prop = xmp.get_property(NS_DC, xpath) self.assertEqual(prop, '300')
def test_count_array_items(self): """Tests XMPMeta method count_array_items.""" filename = pkg_resources.resource_filename(__name__, "samples/test1.xmp") with open(filename, 'r') as fptr: strbuffer = fptr.read() xmp = XMPMeta() xmp.parse_from_str(strbuffer) xmp.set_array_item(NS_DC, "creator", 2, "foo") xmp.append_array_item(NS_DC, "creator", "bar") xmp.append_array_item(NS_DC, "creator", "donuts") self.assertEqual(xmp.count_array_items(NS_DC, "creator"), 4)
def test_does_array_item_exist(self): """Tests XMPMeta method does_array_item_exist. Issue #03""" filename = pkg_resources.resource_filename(__name__, "samples/test1.xmp") with open(filename, 'r') as fptr: strbuffer = fptr.read() xmp = XMPMeta() xmp.parse_from_str(strbuffer) xmp.set_array_item(NS_DC, "creator", 2, "foo") xmp.append_array_item(NS_DC, "creator", "bar") self.assertTrue(xmp.does_array_item_exist(NS_DC, "creator", "foo")) self.assertFalse(xmp.does_array_item_exist(NS_DC, "creator", "blah"))
def tag_images(docker_image): subprocess.call(['mkdir', '-p', 'figures']) subprocess.call("docker run --rm -v {}/figures:/figures " "{} make figures".format(os.getcwd(), docker_image), shell=True) figures = glob.glob('{}/figures/*.png'.format(os.getcwd())) for filename in figures: xmpfile = XMPFiles(file_path=filename, open_forupdate=True) xmp = xmpfile.get_xmp() if xmp == None: xmp = XMPMeta() xmp.append_array_item(libxmp.consts.XMP_NS_DC, 'creator', '{{ "im2sim" : "{}" }}'.format(docker_image), {'prop_array_is_ordered': True, 'prop_value_is_array': True}) xmpfile.put_xmp(xmp) xmpfile.close_file() return None
def write_to_file(): filename = fileEdit.text() if os.path.isfile(filename) == False: print("Error: Media file or reference file missing") else: xmpfile = XMPFiles( file_path=filename, open_forupdate=True) xmp = XMPMeta() # Write creator xmp.append_array_item(consts.XMP_NS_DC, 'creator', escape(str(creatorEdit.text())), {'prop_array_is_ordered': True, 'prop_value_is_array': True}) # Write title xmp.append_array_item(consts.XMP_NS_DC, 'title', escape(str(titleEdit.text())), {'prop_array_is_ordered': True, 'prop_value_is_array': True}) # Write sources for line in referencesEdit.toPlainText().split("\n"): if (len(line) > 1): xmp.append_array_item(consts.XMP_NS_DC, 'source', escape(str(line)), {'prop_array_is_ordered': True, 'prop_value_is_array': True}) """ if (xmpfile.can_put_xmp(xmp) == False): editLabel.setText ('Error: Cannot write metadata to file.') else: """ xmpfile.put_xmp(xmp) xmpfile.close_file() editLabel.setText ('Success! Metadata written to file.')
def create_images(): # actual image color: 255,0,0 img = Image.new("RGB", (100, 20), color='red') text = ImageDraw.Draw(img) text.text((10, 10), "Hello World", fill=(0, 0, 0)) image_wmeta = 'image_wmeta' # thumbnail color: 0,0,255 o = io.BytesIO() secret_thumbnail = Image.new("RGB", (120, 20), color='blue') text = ImageDraw.Draw(secret_thumbnail) text.text((10, 10), "secret thumbnail", fill=(0, 0, 0)) # transform it to bytes secret_thumbnail.save(o, "jpeg") secret_exif_thumbnail = o.getvalue() secret_thumbnail.close() # forbidden image_extension img.save(forbidden_img, "tiff") # bmp doesn't contain critical meta information img.save(image_wmeta + "_bmp" + '.bmp') # for some reasons some of these values don't match the relative specification: # rational numbers are separated at the comma, f.e. 13.37 is represented by [(13), (37)] # http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf#page=47 ... # http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf#page=87 jpg_exif = { "0th": { piexif.ImageIFD.ImageDescription: u"description", piexif.ImageIFD.StripOffsets: 3, piexif.ImageIFD.Artist: u"artist", piexif.ImageIFD.Copyright: u"copyright holder", piexif.ImageIFD.DateTime: u"2012:01:08 10:09:01", }, "Exif": { piexif.ExifIFD.DateTimeOriginal: u"2016:08:07 13:37:10", piexif.ExifIFD.DateTimeDigitized: u"2015:03:07 14:20:30", piexif.ExifIFD.OffsetTime: u"2017:05:09 08:04:04", piexif.ExifIFD.OffsetTimeOriginal: u"2017:04:12 18:15:00", piexif.ExifIFD.OffsetTimeDigitized: u"2016:02:10 11:10:03", piexif.ExifIFD.SubSecTime: u"2017:09:04 10:03:10", piexif.ExifIFD.SubSecTimeOriginal: u"2019:10:03 10:03:10", piexif.ExifIFD.SubSecTimeDigitized: u"2013:10:03 10:03:10", piexif.ExifIFD.CameraOwnerName: u"Cameraname", piexif.ExifIFD.BodySerialNumber: u"body serialnumber", piexif.ExifIFD.LensSerialNumber: u"lens serialnumber", piexif.ExifIFD.UserComment: b"secret comment", }, "GPS": { piexif.GPSIFD.GPSLatitudeRef: u"N", piexif.GPSIFD.GPSLatitude: [(10, 1), (20, 1), (0, 0)], piexif.GPSIFD.GPSLongitudeRef: u"W", piexif.GPSIFD.GPSLongitude: [(10, 1), (20, 1), (0, 0)], piexif.GPSIFD.GPSAltitudeRef: 0, piexif.GPSIFD.GPSAltitude: (200, 1), piexif.GPSIFD.GPSTimeStamp: [(10), (3)], piexif.GPSIFD.GPSSatellites: u"satellites", piexif.GPSIFD.GPSStatus: u"A", piexif.GPSIFD.GPSMeasureMode: u"3", piexif.GPSIFD.GPSDOP: [(1), (4)], piexif.GPSIFD.GPSSpeedRef: u"K", piexif.GPSIFD.GPSSpeed: [(42), (10)], piexif.GPSIFD.GPSTrackRef: u"T", piexif.GPSIFD.GPSTrack: [(21), (123)], piexif.GPSIFD.GPSImgDirectionRef: u"T", piexif.GPSIFD.GPSImgDirection: [(10), (12)], piexif.GPSIFD.GPSMapDatum: u"today", piexif.GPSIFD.GPSDestLatitudeRef: u"N", piexif.GPSIFD.GPSDestLatitude: [(8, 1), (30, 1), (0, 0)], piexif.GPSIFD.GPSDestLongitudeRef: u"E", piexif.GPSIFD.GPSDestLongitude: [(8), (30)], piexif.GPSIFD.GPSDestBearingRef: u"T", piexif.GPSIFD.GPSDestBearing: [(1), (10)], piexif.GPSIFD.GPSDestDistanceRef: u"K", piexif.GPSIFD.GPSDestDistance: [(10), (3)], piexif.GPSIFD.GPSProcessingMethod: b"WLAN", piexif.GPSIFD.GPSAreaInformation: b"area", piexif.GPSIFD.GPSDateStamp: u"2015:10:03 10:03:10", piexif.GPSIFD.GPSDifferential: 1, piexif.GPSIFD.GPSHPositioningError: [(2), (0)], }, "1st": { piexif.ImageIFD.ImageDescription: u"description", piexif.ImageIFD.StripOffsets: 3, piexif.ImageIFD.Artist: u"artist", piexif.ImageIFD.Copyright: u"copyright holder", piexif.ImageIFD.DateTime: u"2013:10:03 10:03:10", }, "thumbnail": secret_exif_thumbnail } png_dict = { "ImageDescription": u"description", "StripOffsets": "3", "Artist": u"artist", "Copyright": u"copyright holder", "DateTime": u"2012:01:08 10:09:01", "DateTimeOriginal": u"2016:08:07 13:37:10", "DateTimeDigitized": u"2015:03:07 14:20:30", "OffsetTime": u"2017:05:09 08:04:04", "OffsetTimeOriginal": u"2017:04:12 18:15:00", "OffsetTimeDigitized": u"2016:02:10 11:10:03", "SubSecTime": u"2017:09:04 10:03:10", "SubSecTimeOriginal": u"2019:10:03 10:03:10", "SubSecTimeDigitized": u"2013:10:03 10:03:10", "CameraOwnerName": u"Cameraname", "BodySerialNumber": u"body serialnumber", "LensSerialNumber": u"lens serialnumber", "UserComment": b"secret comment", "GPSLatitudeRef": u"N", "GPSLatitude": "3 deg 20' 0.00", "GPSLongitudeRef": u"W", "GPSLongitude": "3 deg 20.1' 0.00", "GPSAltitudeRef": "0", "GPSAltitude": "200 m Above Sea Level", "GPSTimeStamp": "03:19:59.999999", "GPSSatellites": u"satellites", "GPSStatus": u"A", "GPSMeasureMode": u"3", "GPSSpeedRef": u"K", "GPSSpeed": "4.2", "GPSTrackRef": u"T", "GPSTrack": "0.1707317073", "GPSImgDirectionRef": u"T", "GPSImgDirection": "0.6333333333", "GPSMapDatum": u"today", "GPSDestLatitudeRef": u"N", "GPSDestLatitude": "3 deg 30' 0.00", "GPSDestLongitudeRef": u"E", "GPSDestLongitude": "0 deg 16' 0.00", "GPSDestBearingRef": u"T", "GPSDestBearing": "0.1", "GPSDestDistanceRef": u"K", "GPSDestDistance": "3.333333333", "GPSProcessingMethod": b"WLAN", "GPSAreaInformation": b"area", "GPSDateStamp": u"2015:10:03 10:03:10", "GPSDifferential": "1", "ImageDescription": u"description", "StripOffsets": "3", "Artist": u"artist", "Copyright": u"copyright holder", "DateTime": u"2013:10:03 10:03:10", } # jpg with exif img.save(image_wmeta + '_jpg' + '.jpg', exif=piexif.dump(jpg_exif)) # copy jpg to jpe, jpeg copyfile(image_wmeta + '_jpg' + '.jpg', image_wmeta + '_jpe' + '.jpe') copyfile(image_wmeta + '_jpg' + '.jpg', image_wmeta + '_jpeg' + '.jpeg') # png exif-part png_info = PngImagePlugin.PngInfo() # copy png metadata for k, v in png_dict.items(): png_info.add_text(k, v, 0) img.save(image_wmeta + '_png' + '.png', "PNG", pnginfo=png_info) img.save(image_wmeta + '_gif' + '.gif') img.close() # xmp for gif and png xmp = XMPMeta() xmp.append_array_item(consts.XMP_NS_DC, 'secret', 'secret information', { 'prop_array_is_ordered': True, 'prop_value_is_array': True }) # gif xmp # TODO BUG Exempi library version >= 2.5 does not work with GIF images created by Pillow. # TODO BUG The format gets not recognized by Exempi. # TODO BUG Maybe a newer Pillow or Exempi version will fix this... # gif_image = XMPFiles(file_path=image_wmeta + '_gif' + ".gif", open_forupdate=True) # gif_image.put_xmp(xmp) # gif_image.close_file() # png part 2 png_image = XMPFiles(file_path=image_wmeta + '_png' + ".png", open_forupdate=True) png_image.put_xmp(xmp) png_image.close_file() return ((image_wmeta + '_' + suffix + "." + suffix) for suffix in ALLOWED_IMG_EXTENSIONS)
def test_exempi_core(self): """Corresponds to test_exempi.TestExempi.test_exempi_core""" filename = pkg_resources.resource_filename(__name__, "samples/test1.xmp") with open(filename, 'r') as fptr: strbuffer = fptr.read() xmp = XMPMeta() xmp.parse_from_str(strbuffer) self.assertTrue(xmp.does_property_exist(NS_TIFF, 'Make')) self.assertFalse(xmp.does_property_exist(NS_TIFF, 'Foo')) prop = xmp.get_property(NS_TIFF, 'Make') self.assertEqual(prop, 'Canon') xmp.set_property(NS_TIFF, 'Make', 'Leica') prop = xmp.get_property(NS_TIFF, 'Make') self.assertEqual(prop, 'Leica') # Some tests correspond to option masks not currently returned via # this interface. item = xmp.get_localized_text(NS_DC, 'rights', None, 'x-default') self.assertEqual(item, "2006, Hubert Figuiere") xmp.set_localized_text(NS_DC, 'rights', 'en', 'en-CA', 'Foo bar') item = xmp.get_localized_text(NS_DC, 'rights', 'en', 'en-US') # Can't look at the actual lang, unlike the original test. self.assertEqual(item, 'Foo bar') xmp.delete_localized_text(NS_DC, 'rights', 'en', 'en-CA') self.assertFalse(xmp.does_property_exist(NS_DC, "rights[1]")) xmp.set_array_item(NS_DC, "creator", 2, "foo") xmp.append_array_item(NS_DC, "creator", "bar") prop = xmp.get_array_item(NS_DC, "creator", 3) self.assertEqual(prop, "bar") xmp.delete_property(NS_DC, "creator[3]") self.assertFalse(xmp.does_property_exist(NS_DC, "creator[3]")) prop = xmp.get_property(NS_EXIF, "DateTimeOriginal") self.assertEqual(prop, "2006-12-07T23:20:43-05:00") the_prop = xmp.get_property_datetime(NS_EXIF, "DateTimeOriginal") self.assertEqual(the_prop.year, 2006) self.assertEqual(the_prop.minute, 20) self.assertEqual(the_prop.tzinfo, pytz.utc) prop = xmp.get_property(NS_XAP, "Rating") self.assertEqual(prop, "3") prop = xmp.get_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius") self.assertEqual(prop, 1.0) xmp.set_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius", 2.5) prop = xmp.get_property_float(NS_CAMERA_RAW_SETTINGS, "SharpenRadius") self.assertEqual(prop, 2.5) prop = xmp.get_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied") self.assertFalse(prop) xmp.set_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied", True) prop = xmp.get_property_bool(NS_CAMERA_RAW_SETTINGS, "AlreadyApplied") self.assertTrue(prop) prop = xmp.get_property_int(NS_EXIF, "MeteringMode") self.assertEqual(prop, 5) xmp.set_property_int(NS_EXIF, "MeteringMode", 10) prop = xmp.get_property_long(NS_EXIF, "MeteringMode") self.assertEqual(prop, 10) xmp.set_property_long(NS_EXIF, "MeteringMode", 32) prop = xmp.get_property_int(NS_EXIF, "MeteringMode") self.assertEqual(prop, 32)
def export_to_xmp_files(args): tmp_faces, img_labels = utils.load_img_labels(args.imgs_root) faces = utils.FACES(tmp_faces) if len(faces.dict_by_files) == 0: print('no faces loaded') exit() total_images = utils.get_images_in_dir_rec(args.imgs_root) for f in total_images: img_path = os.path.splitext(f)[0] + os.path.splitext(f)[1].lower() if os.path.dirname( img_path ) != args.mask_folder and args.mask_folder != None or img_path.lower( ).endswith('.png'): continue xmp_path = os.path.splitext(f)[0] + '.xmp' if os.path.exists(xmp_path): with open(xmp_path, 'r') as fptr: strbuffer = fptr.read() xmp = XMPMeta() xmp.parse_from_str(strbuffer) else: xmpfile = XMPFiles(file_path=f, open_forupdate=True) xmp = xmpfile.get_xmp() # print(f) kw_faces, kw_tags, kw_categories, kw_labels, kw_miscs = get_keywords( xmp) kw_tags = [] kw_categories = [] kw_miscs = [] if img_path in faces.dict_by_files: names = faces.get_names(faces.dict_by_files[img_path]) # remove detected, deleted and unknown unwanted_names = {'detected', 'deleted', 'unknown'} names = [ele for ele in names if ele not in unwanted_names] face_names = prepare_names(names, 'f ') else: # if not os.path.exists(xmp_path): # continue face_names = [] labels = [] if img_path in img_labels: if len(img_labels[img_path].tags) != 0: labels += prepare_names([ t[0].lower() for t in img_labels[img_path].tags if t[1] >= 30 ], 'l ') if len(img_labels[img_path].categories) != 0: labels += prepare_names( [c[0].lower() for c in img_labels[img_path].categories], 'l ') if hasattr(img_labels[img_path], 'gcloud_labels'): labels += prepare_names( [l.lower() for l in img_labels[img_path].gcloud_labels], 'l ') if hasattr(img_labels[img_path], 'gcloud_objects'): labels += prepare_names( [l.lower() for l in img_labels[img_path].gcloud_objects], 'l ') if hasattr(img_labels[img_path], 'gcloud_web'): labels += prepare_names( [l.lower() for l in img_labels[img_path].gcloud_web], 'l ') if hasattr(img_labels[img_path], 'gcloud_landmarks'): labels += prepare_names([ l.lower() for l in img_labels[img_path].gcloud_landmarks[::2] ], 'l ') labels = list(set(labels)) if sorted(face_names) != sorted(kw_faces) or sorted(labels) != sorted( kw_labels) or not os.path.exists(xmp_path): xmp.delete_property(consts.XMP_NS_DC, 'subject') for face in face_names: xmp.append_array_item(consts.XMP_NS_DC, 'subject', face, { 'prop_array_is_ordered': True, 'prop_value_is_array': True }) for l in labels: xmp.append_array_item(consts.XMP_NS_DC, 'subject', l, { 'prop_array_is_ordered': True, 'prop_value_is_array': True }) print('exporting file: {}'.format(os.path.basename(xmp_path))) with open(xmp_path, 'w') as fptr: fptr.write(xmp.serialize_to_str(omit_packet_wrapper=True))
def worker(filepath): # initialize saucenao saucenao_core = SauceNao( directory='directory', databases=9, # 999 by default, 5 for pixiv, 9 for booru. minimum_similarity=65, combine_api_types=False, api_key=saucenao_api_key, exclude_categories='', move_to_categories=False, use_author_as_category=False, output_type=SauceNao.API_JSON_TYPE, start_file='', log_level=logging.ERROR, title_minimum_similarity=90) # search image on saucenao try: result = search(saucenao_core, filepath) except requests.exceptions.ConnectionError: print("Failed to connect saucenao!") return -1 except saucenao.exceptions.DailyLimitReachedException: print("Saucenao daily limit reached! try 1 hour later!") return -2 if (len(result) is 0): print('Image not found on danbooru!') return 1 else: danbooru_id = result[0]['data']['danbooru_id'] print('Image Found, ID=' + str(danbooru_id)) # GET danbooru tag json try: http = urllib3.PoolManager() # disable https cert check warning urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) url = 'https://danbooru.donmai.us/posts/' + str( danbooru_id) + '.json' headers = urllib3.util.make_headers(basic_auth=danbooru_login + ':' + danbooru_api_key) r = http.request('GET', url, headers=headers) r_data = r.data if isinstance(r_data, bytes): r_data = str(r_data, 'utf-8') tags = json.loads(r_data)['tag_string'] taglist = tags.split() except requests.exceptions.ConnectionError: print('failed to GET tag data from danbooru') return -1 # Write XMP Metadata to image xmpfile = XMPFiles(file_path=filepath, open_forupdate=True) xmp = xmpfile.get_xmp() # if image has no xmp data, create one if (xmp is None): xmp = XMPMeta() # write the tags for each in taglist: # check whether XMP includes 'subject' property, # if not, create a new one if (not xmp.does_property_exist(consts.XMP_NS_DC, 'subject')): xmp.append_array_item(consts.XMP_NS_DC, 'subject', each, { 'prop_array_is_ordered': True, 'prop_value_is_array': True }) # check whether tag has been written to file if (not xmp.does_array_item_exist(consts.XMP_NS_DC, 'subject', each)): xmp.append_array_item(consts.XMP_NS_DC, 'subject', each) if (xmpfile.can_put_xmp(xmp)): xmpfile.put_xmp(xmp) xmpfile.close_file() return 0 else: print('Unable to write XMP data!') return -1