def test_tiff(self): """Write to a TIFF that does not already have the XMP tag.""" srcfile = pkg_resources.resource_filename(__name__, "fixtures/zeros.tif") with tempfile.NamedTemporaryFile(suffix='.tif') as tfile: shutil.copyfile(srcfile, tfile.name) xmpf = XMPFiles() xmpf.open_file(file_path=tfile.name, open_forupdate=True) # Since it's a TIFF, it already has everything possible from the # TIFF IFD filled in into the TIFF namespace. xmp = xmpf.get_xmp() xmp.set_property(NS_DC, "rights", "no one in particular") xmpf.put_xmp(xmp) xmpf.close_file() xmpf.open_file(file_path=tfile.name) xmp = xmpf.get_xmp() xmpf.close_file() # TODO: explain why this happened. prop = xmp.get_property(NS_DC, "rights") prop2 = xmp.get_localized_text(NS_DC, "rights", None, "x-default") self.assertEqual(prop2, "no one in particular")
def plot_file(self,date,p,var,dirout): ''' Red line is reference (biofloat, mooring or vessel) Blue line is model ''' floatname = p.name() filename =dirout+"/"+date.strftime('%Y%m%d') +"_"+floatname+"_"+var+ ".png" pl.figure() pl.plot(self.Model,self.Depth,label="Model") pl.plot(self.Ref,self.Depth,label="Float") pl.legend(loc='upper right') pl.ylabel("depth") figtitle = var+" date="+date.strftime('%Y/%m/%d')+" float="+floatname pl.title(figtitle) pl.gca().invert_yaxis() pl.savefig(filename) pl.close() import libxmp import libxmp.utils from libxmp import XMPFiles, consts xmpfile = XMPFiles( file_path=filename, open_forupdate=True ) xmp = xmpfile.get_xmp() if xmp is None: xmp = libxmp.XMPMeta() xmp.set_property(consts.XMP_NS_DC, 'float', floatname ) xmp.set_property(consts.XMP_NS_DC, 'date', date.strftime('%Y%m%d') ) xmp.set_property(consts.XMP_NS_DC, 'hour', date.strftime('%H:%M:%S') ) xmp.set_property(consts.XMP_NS_DC, 'var', var ) xmp.set_property(consts.XMP_NS_DC, 'position.lat',str(p.lat)+"N") xmp.set_property(consts.XMP_NS_DC, 'position.lon',str(p.lon)+"E") xmpfile.put_xmp(xmp) xmpfile.close_file()
def UpdateFileMetadata(filename, datetime): exif = GExiv2.Metadata(filename) if exif is not None: fileDate = GetDateFromExif(exif) if fileDate is not None: fileDate = datetime.strptime(fileDate, DATE_FORMAT) # date within acceptable limit. don't update if abs((fileDate - datetime).days) <= FILE_METADATA_DATE_TOLERANCE: return log('Updating exif: %s to date: %s', \ filename, datetime.strftime(DATE_FORMAT)) if DRY_RUN == False: if exif is not None: exif['Exif.Photo.DateTimeOriginal'] = datetime.strftime( DATE_FORMAT) exif['Exif.Photo.DateTimeDigitized'] = datetime.strftime( DATE_FORMAT) exif['Exif.Image.DateTime'] = datetime.strftime(DATE_FORMAT) exif['Exif.Image.DateTimeOriginal'] = datetime.strftime( DATE_FORMAT) exif.save_file() xmpfile = XMPFiles(file_path=filename, open_forupdate=True) xmp = xmpfile.get_xmp() if xmp is not None: for xmpConst in XMP_CONSTANTS: for dateConst in DATE_CONSTANTS: if xmp.does_property_exist(xmpConst, dateConst): xmp.set_property( \ xmpConst, dateConst, datetime.strftime(DATE_FORMAT_XMP)) if (xmpfile.can_put_xmp(xmp)): xmpfile.put_xmp(xmp) xmpfile.close_file()
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 terminal_write(file): # get xmp from file xmpfile = XMPFiles(file_path=file, open_forupdate=True) xmp = xmpfile.get_xmp() if check_xmp_writable(file) == True: #if xmp can be written to file if check_inspo_xmp(file) == False: #if INSPO xmp does not exist # register or update INSPO namespace URI xmp.register_namespace(INSPO_URI, "INSPO") # for each possible article for article in ARTICLES: value = input("What " + article + " are they wearing?: ") # ask if they are wearing a certain article of clothing if value == "": # if the value is empty then pass pass else: # else set that article of clothing xmp.set_property(INSPO_URI, article, value) xmpfile.put_xmp(xmp) xmpfile.close_file() else: xmpfile.close_file() print("INSPO DATA ALREADY EXISTS") return else: xmpfile.close_file() print("XMP NOT WRITEABLE") return
def dictonary_write(file, dict): # get xmp from file xmpfile = XMPFiles(file_path=file, open_forupdate=True) xmp = xmpfile.get_xmp() if check_xmp_writable(file) == True: #if xmp can be written to file if check_inspo_xmp(file) == False: #if INSPO xmp does not exist # register or update INSPO namespace URI xmp.register_namespace(INSPO_URI, "INSPO") # for each possible article for article in ARTICLES: try: value = dict[article] xmp.set_property(INSPO_URI, article, value) except: pass xmpfile.put_xmp(xmp) xmpfile.close_file() return else: xmpfile.close_file() print("INSPO DATA ALREADY EXISTS") return else: xmpfile.close_file() print("XMP NOT WRITEABLE") return
def test_jpeg(self): """Create XMP from scratch to store in a jpeg.""" srcfile = pkg_resources.resource_filename(__name__, "samples/BlueSquare.jpg") with tempfile.NamedTemporaryFile(suffix='.tif', mode='wb') as tfile: # Do some surgery on the file, remove existing xmp. # The APP1 marker segment in question starts at byte 2156, has # length of 4813 with open(srcfile, 'rb') as infptr: # Write the SOI marker tfile.write(infptr.read(2)) # Skip over ALL the APP0, APP1 segments. infptr.seek(21619) tfile.write(infptr.read()) tfile.flush() xmpf = XMPFiles() xmpf.open_file(file_path=tfile.name, open_forupdate=True) xmp = xmpf.get_xmp() xmp.set_property(NS_DC, "Title", u'Stürm und Drang') # Construct the properties that would have been filled in had the # APP0 segment been left in place. xmp.set_property(NS_TIFF, "Orientation", "1") xmp.set_property(NS_TIFF, "XResolution", "720000/10000") xmp.set_property(NS_TIFF, "YResolution", "720000/10000") xmp.set_property(NS_TIFF, "ResolutionUnit", "2") xmpf.put_xmp(xmp) xmpf.close_file() xmpf = XMPFiles() xmpf.open_file(file_path=tfile.name) xmp = xmpf.get_xmp() prop = xmp.get_property(NS_DC, "Title") self.assertEqual(prop, u'Stürm und Drang') prop = xmp.get_property(NS_TIFF, "Orientation") self.assertEqual(prop, "1") prop = xmp.get_property(NS_TIFF, "XResolution") self.assertEqual(prop, "720000/10000") prop = xmp.get_property(NS_TIFF, "YResolution") self.assertEqual(prop, "720000/10000") prop = xmp.get_property(NS_TIFF, "ResolutionUnit") self.assertEqual(prop, "2") xmpf.close_file()
def main(): options = getoptions() logging.basicConfig(level=logging.INFO, format="%(levelname)s %(message)s") logger = logging.getLogger() vars = { 'UsePanoramaViewer': 'True', 'ProjectionType': 'equirectangular', } for vstr in options.vars: for elem in vstr.split(','): key, value = elem.split('=') if key in namespace: vars[key] = value else: logger.warn("Key {0} is invalid.".format(key)) for filename in options.filenames: logger.info("Filename: {0}".format(filename)) xmpfile = XMPFiles(file_path=filename, open_forupdate=True) xmp = xmpfile.get_xmp() try: assert xmp is not None except AssertionError: logger.warn("Metadata is not available for {0}.".format(filename)) continue xmp.register_namespace(GPano, 'GPano') width, height = imagesize.get(filename) width = "{0}".format(width) height = "{0}".format(height) # width = xmp.get_property(consts.XMP_NS_EXIF, 'PixelXDimension' ) # height = xmp.get_property(consts.XMP_NS_EXIF, 'PixelYDimension' ) # assert width != '', "No width read." # assert height != '', "No height read." for name in namespace: if name in vars: if xmp.does_property_exist(GPano, name): logger.info("Overwrite: {0} {1}->{2}".format( name, xmp.get_property(GPano, name), vars[name])) else: logger.info("Set: {0} {1}".format(name, vars[name])) xmp.set_property(GPano, name, vars[name]) elif name in [ 'FullPanoWidthPixels', 'CroppedAreaImageWidthPixels' ]: if not xmp.does_property_exist(GPano, name): logger.info("Set default: {0} {1}".format(name, width)) xmp.set_property(GPano, name, width) elif name in [ 'FullPanoHeightPixels', 'CroppedAreaImageHeightPixels' ]: if not xmp.does_property_exist(GPano, name): logger.info("Set default: {0} {1}".format(name, height)) xmp.set_property(GPano, name, height) xmpfile.put_xmp(xmp) xmpfile.close_file()
def get_tags_from_xmp(self, file_path): xmpfile = XMPFiles(file_path=file_path, open_forupdate=True) xmp = xmpfile.get_xmp() property_was_removed = False for index in range(5, 0, -1): property_was_removed |= self.remove_geo_xmp_property( xmp, consts.XMP_NS_DC, 'subject[%s]' % (index)) if property_was_removed: print('Updating %s' % file_path) xmpfile.put_xmp(xmp) xmpfile.close_file() return
def update_xmp(imgpath, keywords): """ updates the xmp data in the image, or creates a sidecar xmp """ # Check if a sidecar file already exists if os.path.isfile(imgpath + '.xmp'): imgpath = imgpath + '.xmp' # NEF requires sidecar embeddedXmpFormats = ['jpg', 'png', 'tif', 'dng'] if not imgpath.lower().endswith(tuple(embeddedXmpFormats)): # create and use sidecar file imgpath = imgpath + '.xmp' with open(imgpath, 'w+') as f: f.write(blank_xmp()) print('wrote in' + imgpath) xmpfiledict = file_to_dict(imgpath) existing_keywords = [] try: dc = [] dc.append(xmpfiledict[consts.XMP_NS_DC]) existing_keywords = [x[1] for x in dc] except: print('nothing') print('existing_keywords') print(existing_keywords) xmpfile = XMPFiles(file_path=imgpath, open_forupdate=True) xmp = xmpfile.get_xmp() print(xmp) keywords_to_add = [x for x in keywords if x not in existing_keywords] print('keywords to add') print(keywords_to_add) def add_keyword(k): """ helper func """ xmp.append_array_item(consts.XMP_NS_DC, u'subject', k) _ = [add_keyword(x) for x in keywords_to_add] if xmpfile.can_put_xmp(xmp): xmpfile.put_xmp(xmp) else: xmpfile.close_file() raise Exception('Cannot write xmp to ' + imgpath) xmpfile.close_file() return 0
def test_cannot_inject_xmp_info_pdf(self): """Verify behavior of not being able to inject XMP into barren PDF""" # See issue 40 srcfile = pkg.resource_filename(__name__, os.path.join("fixtures", "zeros.pdf")) with tempfile.NamedTemporaryFile() as tfile: shutil.copyfile(srcfile, tfile.name) xmpf = XMPFiles() xmpf.open_file(tfile.name, open_forupdate=True) xmp = XMPMeta() xmp.set_property(NS_PHOTOSHOP, "ICCProfile", "foo") with self.assertRaises(XMPError): xmpf.put_xmp(xmp) xmpf.close_file()
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 remove_XMPMeta(file): xmpfile = XMPFiles(file_path=file, open_forupdate=True) xmp = xmpfile.get_xmp() xmp.set_property(consts.XMP_NS_PDF, 'pdf:Producer', 'Document Converter') xmp.set_property(consts.XMP_NS_XMP, 'xmp:CreatorTool', 'Document Converter') xmp.set_property(consts.XMP_NS_XMP_MM , 'xmpMM:DocumentID', '') xmp.delete_property(consts.XMP_NS_DC, 'dc:format') xmp.delete_property(consts.XMP_NS_DC, 'dc:title') xmp.delete_property(consts.XMP_NS_DC, 'dc:creator') xmp.delete_property(consts.XMP_NS_DC, 'dc:description') try: xmpfile.put_xmp(xmp) except: xmpfile.close_file() return xmpfile.close_file()
def ocultar_informacion(self, img_name, tag, content): xmpfile = XMPFiles(file_path=img_name, open_forupdate=True) tipo = Image.open(img_name).format # Obtenemos el tipo de la imagen. if tipo == 'JPEG': # Si la imagen es JPEG, almacenamos el contenido en los campos consts.XMP_NS_JPEG xmp = xmpfile.get_xmp() xmp.set_property(consts.XMP_NS_JPEG, tag, content) else: # Si la imagen es PNG if xmpfile.get_xmp() is None: # Comprobamos si tiene campos XMP, sino, creamos uno vacío. xmp = XMPMeta() else: # Si tiene campos XMP, los cogemos. xmp = xmpfile.get_xmp() xmp.set_property(consts.XMP_NS_PNG, tag, content) # Almacenamos el contenido en los campos consts.XMP_NS_PNG xmpfile.put_xmp(xmp) xmpfile.close_file()
def embed_xmp(filename, dt): t = calendar.timegm(dt.timetuple()) os.utime(filename, (t, t)) os.system('SetFile -d "%s" "%s"' % ( dt.strftime("%m/%d/%Y 00:00:00"), filename.encode('utf-8'), )) xmpfile = XMPFiles(file_path=filename, open_forupdate=True) xmp = xmpfile.get_xmp() xmp.set_property(consts.XMP_NS_XMP, "CreateDate", dt.isoformat()) if xmpfile.can_put_xmp(xmp): xmpfile.put_xmp(xmp) xmpfile.close_file() return True else: xmpfile.close() return False
def mutate(self, info, input): abs_path = Path(BASE_DIR, input["path"]) if not abs_path.exists(): raise Exception("Image not found") if not (isinstance(input["rating"], int) and -1 <= input["rating"] <= 5): raise Exception("Rating must be an integer from 1 to 5") image = {"path": abs_path} xmpfile = XMPFiles(file_path=str(abs_path), open_forupdate=True) xmp = xmpfile.get_xmp() # WISHLIST don't write if rating didn't change xmp.set_property(XMP_NS_XMP, "xmp:Rating", str(input["rating"])) if not xmpfile.can_put_xmp(xmp): raise Exception("Can't write xmp metadata back to image") xmpfile.put_xmp(xmp) xmpfile.close_file() return SetRatingPayload(image=image)
def main(): path = cli() proj = path.parts[-1] stamp = path.joinpath(proj + "_PPKStamp.csv") cols = ["name","lat","lon","elev"] st = pd.read_csv(stamp, names=cols, comment='#') for i in range(len(st)): jpg = path.joinpath(st["name"][i] + ".JPG") exif = piexif.load(str(jpg)) xmpfile = XMPFiles(file_path=str(jpg), open_forupdate=True) xmp = xmpfile.get_xmp() DJIns = xmp.get_namespace_for_prefix("drone-dji") xmp.set_property(DJIns, 'AbsoluteAltitude', "+%.4f" % st["elev"][i]) xmp.set_property(DJIns, 'GpsLatitude', "%.10f" % st["lat"][i]) xmp.set_property(DJIns, 'GpsLongitude', "%.10f" % st["lon"][i]) #xmp.set_property(DJIns, 'GpsLongtitude', "+%.10f" % st["lon"][i]) xmpfile.put_xmp(xmp) xmpfile.close_file() lat = abs(st["lat"][i]) latd = int(lat) latm = int((lat-latd)*60) lats = (lat-latd-latm/60)*3600 lon = abs(st["lon"][i]) lond = int(lon) lonm = int((lon-lond)*60) lons = (lon-lond-lonm/60)*3600 exif["GPS"][2] = ((latd, 1), (latm, 1), (int(lats*1000000), 1000000)) exif["GPS"][4] = ((lond, 1), (lonm, 1), (int(lons*1000000), 1000000)) exif["GPS"][6] = (int(st["elev"][i]*1000), 1000) exifBytes = piexif.dump(exif) piexif.insert(exifBytes, str(jpg))
def test_tiff_smarthandler(self): """Verify action of TIFF smarthandler when tag length > 255""" # See issue 12 srcfile = pkg.resource_filename(__name__, "fixtures/zeros.tif") with tempfile.NamedTemporaryFile(suffix='.tif') as tfile: shutil.copyfile(srcfile, tfile.name) # Create a tag with 280 chars. xmpf = XMPFiles() xmpf.open_file(tfile.name, open_forupdate=True) xmp = xmpf.get_xmp() blurb = "Some really long text blurb " xmp.set_property(NS_PHOTOSHOP, 'Headline', blurb * 10) xmpf.put_xmp(xmp) xmpf.close_file() xmpf.open_file(tfile.name, usesmarthandler=True) xmp = xmpf.get_xmp() prop = xmp.get_property(NS_PHOTOSHOP, "Headline") xmpf.close_file() self.assertEqual(prop, blurb * 10)
def test_can_inject_xmp_info_png(self): """Verify behavior of being able to inject XMP into barren PNG""" # See issue 40 srcfile = pkg.resource_filename(__name__, os.path.join("fixtures", "zeros.png")) with tempfile.NamedTemporaryFile() as tfile: shutil.copyfile(srcfile, tfile.name) xmpf = XMPFiles() xmpf.open_file(tfile.name, open_forupdate=True) xmp = XMPMeta() xmp.set_property(NS_PHOTOSHOP, "ICCProfile", "foo") xmpf.put_xmp(xmp) xmpf.close_file() xmpf.open_file(tfile.name, usesmarthandler=True) xmp = xmpf.get_xmp() prop = xmp.get_property(NS_PHOTOSHOP, "ICCProfile") xmpf.close_file() self.assertEqual(prop, "foo")
def test_sturm_und_drang(self): """Should be able to write a property which includes umlauts.""" srcfile = pkg_resources.resource_filename(__name__, "fixtures/zeros.tif") with tempfile.NamedTemporaryFile(suffix='.tif') as tfile: shutil.copyfile(srcfile, tfile.name) expected_value = u'Stürm und Drang' xmpf = XMPFiles() xmpf.open_file(file_path=tfile.name, open_forupdate=True) xmp = xmpf.get_xmp() xmp.set_property(NS_DC, "Title", expected_value) xmpf.put_xmp(xmp) xmpf.close_file() xmpf = XMPFiles() xmpf.open_file(file_path=tfile.name) xmp = xmpf.get_xmp() actual_value = xmp.get_property(NS_DC, "Title") xmpf.close_file() self.assertEqual(actual_value, expected_value)
def embed_xmp(filename, dt): t = calendar.timegm(dt.timetuple()) os.utime(filename, (t, t)) os.system('SetFile -d "%s" "%s"' % ( dt.strftime("%m/%d/%Y 00:00:00"), filename.encode('utf-8'), )) xmpfile = XMPFiles(file_path=filename, open_forupdate=True) xmp = xmpfile.get_xmp() xmp.set_property( consts.XMP_NS_XMP, "CreateDate", dt.isoformat() ) if xmpfile.can_put_xmp(xmp): xmpfile.put_xmp(xmp) xmpfile.close_file() return True else: xmpfile.close() return False
def write_xmp(filename, field, value, sidecar=False): """Write a field into a files XMP store, if sidecar is True and the file format doesn't support writing inline a sidecar .xmp file will be created. Args: filename (str): The full path to file read to write XMP data into field (str|None) sidecar (bool): If True and the file doesn't support XMP inline a .xmp file with the same name as the ``filename`` will be created with an .xmp extension. Example: test.txt -> test.txt.xmp Returns: On success: The path to the file written On failure: False """ xmpfile = XMPFiles(file_path=filename, open_forupdate=True) xmp = xmpfile.get_xmp() if xmp is None and sidecar: return write_xmp_sidecar(filename, field, value) elif xmp is None: return False if _read_xmp_field(xmp, field) == value: return filename xmp.set_property(consts.XMP_NS_DC, field, value) if xmpfile.can_put_xmp(xmp): xmpfile.put_xmp(xmp) xmpfile.close_file() return filename else: return False
#import files from libxmp import XMPFiles #set image to add data to image = "image.jpg" #read file xmpfile = XMPFiles(file_path=image, open_forupdate=True) #set INSPONIZER URI inspoURI = "https://www.claytondunavant.com/inspo" #get xmp from file xmp = xmpfile.get_xmp() #register or update INSPO namespace URI xmp.register_namespace(inspoURI, "INSPO") #set shirt property to UNIQLO xmp.set_property(inspoURI, u"shirt", u"Uniqlo U T-Shirt") #if you can write new xmp, write it if xmpfile.can_put_xmp(xmp) == True: xmpfile.put_xmp(xmp) #close the file xmpfile.close_file()
class DCFile(object): def __init__(self, fpath, lang='x-default'): self._xmp = None self._xmpfile = None self.fpath = fpath self.lang = lang self.allow_identifier_change = False self.array_properties = { 'prop_array_is_ordered': True, 'prop_value_is_array': True } self.terms = [ 'dccoverage', 'dccreator', 'dcdescription', 'dcidentifier', 'dcpublisher', 'dcrelation', 'dcsource', 'dcsubject', 'dctitle', 'dctype', ] self.open() def open(self): self._xmpfile = XMPFiles(file_path=self.fpath, open_forupdate=True) self._xmp = self._xmpfile.get_xmp() def close(self): if self._xmpfile is not None: if self._xmp is not None: self._xmpfile.put_xmp(self._xmp) self._xmpfile.close_file() self._xmp = None self._xmpfile = None def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.close() # ----------------------------------- # Simple strings @property def dcidentifier(self): return self._xmp.get_property(consts.XMP_NS_DC, 'identifier') @dcidentifier.setter def dcidentifier(self, v): existing_id = self.dcidentifier if self.allow_identifier_change or (existing_id is None or existing_id == ''): res = self._xmp.set_property(consts.XMP_NS_DC, 'identifier', v) raise ValueError("Identifier already set and is immutable.") @property def dcsource(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'source'): return None return self._xmp.get_property(consts.XMP_NS_DC, 'source') @dcsource.setter def dcsource(self, v): res = self._xmp.set_property(consts.XMP_NS_DC, 'source', v) @dcsource.deleter def dcsource(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'source'): return self._xmp.delete_property(consts.XMP_NS_DC, 'source') @property def dccoverage(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'coverage'): return None return self._xmp.get_property(consts.XMP_NS_DC, 'coverage') @dccoverage.setter def dccoverage(self, v): res = self._xmp.set_property(consts.XMP_NS_DC, 'coverage', v) @dccoverage.deleter def dccoverage(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'coverage'): return self._xmp.delete_property(consts.XMP_NS_DC, 'coverage') # ----------------------------------- # Localized strings @property def dctitle(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'title'): return None v = self._xmp.get_localized_text(consts.XMP_NS_DC, 'title', 'Alt', self.lang) return v @dctitle.setter def dctitle(self, v): res = self._xmp.set_localized_text(consts.XMP_NS_DC, 'title', 'Alt', self.lang, v) @dctitle.deleter def dctitle(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'title'): return self._xmp.delete_property(consts.XMP_NS_DC, 'title') @property def dcdescription(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'description'): return None v = self._xmp.get_localized_text(consts.XMP_NS_DC, 'description', 'Alt', self.lang) return v @dcdescription.setter def dcdescription(self, v): res = self._xmp.set_localized_text(consts.XMP_NS_DC, 'description', 'Alt', self.lang, v) @dcdescription.deleter def dcdescription(self): if not self._xmp.does_property_exist(consts.XMP_NS_DC, 'description'): return self._xmp.delete_property(consts.XMP_NS_DC, 'description') # ----------------------------------- # multi-values @property def dccreator(self): ''' :return: list of creator values ''' res = [] n = self._xmp.count_array_items(consts.XMP_NS_DC, 'creator') for i in xrange(0, n): res.append( self._xmp.get_array_item(consts.XMP_NS_DC, 'creator', i + 1)) return res @dccreator.setter def dccreator(self, v): ''' Set or append creator v may be single item or list. Appended to existing entries if any. ''' if not isinstance(v, list): v = [ v, ] for sv in v: self._xmp.append_array_item(consts.XMP_NS_DC, 'creator', sv, self.array_properties) @dccreator.deleter def dccreator(self): self._xmp.delete_property(consts.XMP_NS_DC, 'creator') @property def dcsubject(self): ''' :return: list of creator values ''' res = [] n = self._xmp.count_array_items(consts.XMP_NS_DC, 'subject') for i in xrange(0, n): res.append( self._xmp.get_array_item(consts.XMP_NS_DC, 'subject', i + 1)) return res @dcsubject.setter def dcsubject(self, v): ''' Set or append subject v may be single item or list. Appended to existing entries if any. ''' if not isinstance(v, list): v = [ v, ] for sv in v: self._xmp.append_array_item(consts.XMP_NS_DC, 'subject', sv, self.array_properties) @dcsubject.deleter def dcsubject(self): self._xmp.delete_property(consts.XMP_NS_DC, 'subject') @property def dctype(self): ''' :return: list of creator values ''' res = [] n = self._xmp.count_array_items(consts.XMP_NS_DC, 'type') for i in xrange(0, n): res.append( self._xmp.get_array_item(consts.XMP_NS_DC, 'type', i + 1)) return res @dctype.setter def dctype(self, v): ''' Set or append subject v may be single item or list. Appended to existing entries if any. ''' if not isinstance(v, list): v = [ v, ] for sv in v: self._xmp.append_array_item(consts.XMP_NS_DC, 'type', sv, self.array_properties) @dctype.deleter def dctype(self): self._xmp.delete_property(consts.XMP_NS_DC, 'type') @property def dcrelation(self): ''' :return: list of creator values ''' res = [] n = self._xmp.count_array_items(consts.XMP_NS_DC, 'relation') for i in xrange(0, n): res.append( self._xmp.get_array_item(consts.XMP_NS_DC, 'relation', i + 1)) return res @dcrelation.setter def dcrelation(self, v): ''' Set or append subject v may be single item or list. Appended to existing entries if any. ''' if not isinstance(v, list): v = [ v, ] for sv in v: self._xmp.append_array_item(consts.XMP_NS_DC, 'relation', sv, self.array_properties) @dcrelation.deleter def dcrelation(self): self._xmp.delete_property(consts.XMP_NS_DC, 'relation') @property def dcpublisher(self): ''' :return: list of creator values ''' res = [] n = self._xmp.count_array_items(consts.XMP_NS_DC, 'publisher') for i in xrange(0, n): res.append( self._xmp.get_array_item(consts.XMP_NS_DC, 'publisher', i + 1)) return res @dcpublisher.setter def dcpublisher(self, v): ''' Set or append subject v may be single item or list. Appended to existing entries if any. ''' if not isinstance(v, list): v = [ v, ] for sv in v: self._xmp.append_array_item(consts.XMP_NS_DC, 'publisher', sv, self.array_properties) @dcpublisher.deleter def dcpublisher(self): self._xmp.delete_property(consts.XMP_NS_DC, 'publisher')
XMP_GIMAGE = 'http://ns.google.com/photos/1.0/image/' XMP_GPANO = 'http://ns.google.com/photos/1.0/panorama/' XMPMeta.register_namespace(XMP_GIMAGE, 'GImage') XMPMeta.register_namespace(XMP_GPANO, 'GPano') # Set GPano properties lxmp.set_property(XMP_GPANO, 'ProjectionType', 'equirectangular') lxmp.set_property_int(XMP_GPANO, 'CroppedAreaLeftPixels', image_width/2) lxmp.set_property_int(XMP_GPANO, 'CroppedAreaTopPixels', 0) lxmp.set_property_int(XMP_GPANO, 'CroppedAreaImageWidthPixels', image_width) lxmp.set_property_int(XMP_GPANO, 'CroppedAreaImageHeightPixels', image_height) lxmp.set_property_int(XMP_GPANO, 'FullPanoWidthPixels', image_width*2) lxmp.set_property_int(XMP_GPANO, 'FullPanoHeightPixels', image_height) lxmp.set_property_int(XMP_GPANO, 'InitialViewHeadingDegrees', 180) # Encode right image to BASE64 rimage_data = open(rimage_path, 'rt').read() rimage_base64 = base64.b64encode(rimage_data) # Set GImage properties lxmp.set_property(XMP_GIMAGE, 'Mime', 'image/jpeg') lxmp.set_property(XMP_GIMAGE, 'Data', rimage_base64) # Put XMP. if vrimage_file.can_put_xmp(lxmp): vrimage_file.put_xmp(lxmp) print(vrimage_file.get_xmp()) print("Done!") vrimage_file.close_file()
import glob from tqdm import tqdm directries = glob.glob("*_*") for directry in tqdm(directries): os.chdir(directry) files = glob.glob("*.JPG") os.chdir('..') try: os.mkdir('normal/%s_normal ' % directry) except FileExistsError: pass for file in files: ##OpenCV処理 image = cv2.imread('%s/%s' % (directry, file)) img_normal = (image - np.mean(image)) / np.std(image) * 55 + 140 cv2.imwrite('normal/%s_normal/%s' % (directry, file), img_normal) ##XMP処理 xmpfile = XMPFiles(file_path="%s/%s" % (directry, file), open_forupdate=True) xmp = xmpfile.get_xmp() xmpfile.close_file() xmpfile_normal = XMPFiles(file_path="normal/%s_normal/%s" % (directry, file), open_forupdate=True) xmp_normal = xmpfile_normal.get_xmp() xmp_normal = xmp xmpfile_normal.put_xmp(xmp_normal) xmpfile_normal.close_file()
def kml2gevr(kml, output_dir, desiredHeight, bgColor, textColor): global font points = [] # get the point data from the kml file try: entry = getPoint(kml.Document.Placemark) if ('lon' in entry): points.append(entry) except: # Assume exception is due to multiple placemarks in the file # kml file contains multiple points for child in kml.Document.Folder.Placemark: entry = getPoint(child) if ('lon' in entry): points.append(entry) # get elevation from google maps script_dir = os.path.dirname(__file__) keyfile = open(os.path.join(script_dir, "googleapi.key"), 'r') key = keyfile.read().strip() client = googlemaps.Client(key) googleQuery = [(entry['lat'], entry['lon']) for entry in points] elevations = client.elevation(googleQuery) for i, elev in enumerate(elevations): points[i]['elev'] = elev['elevation'] # create the image files for entry in points: image = ImageText((1512, 950), background=bgColor) # (w, height) = image.write_text( ( 'center', 75) , entry['name'], # font_filename=font, font_size='fill', max_width=1400, # color=textColor) image.write_text_box(((1512 - 600) / 2.0, 110), entry['desc'], box_width=725, font_filename=font, font_size=72, color=textColor, place='center') newFile = tempfile.NamedTemporaryFile(suffix=".jpg", dir=output_dir, delete=False) newFile.close() image.save(newFile.name) entry['filename'] = newFile.name # now open that file back up and write an XMP containing the google protocol buffer to it gevrplace = gevrplace_pb2.GEVRPlace() temp = gevrplace.summary.location.extend([entry['name'], ""]) gevrplace.summary.copyright = "Imagery ©2016 Google, Data SIO, NOAA, U.S. Navy, NGA, GEBCO, Google, IBCAO, INEGI, Landsat" gevrplace.summary.unknown1 = 438 gevrplace.summary.unknown2 = 0 gevrplace.summary.unknown3 = 756 gevrplace.summary.unknown4 = 850 gevrplace.places.savedPlace.Title = entry['name'] gevrplace.places.savedPlace.SubTitle = entry['desc'] gevrplace.places.savedPlace.location.latLong.lat = entry['lat'] gevrplace.places.savedPlace.location.latLong.lon = entry['lon'] gevrplace.places.savedPlace.location.latLong.earthRadius = -6371010.0 gevrplace.places.savedPlace.location.picParams.roll = 0.0280364837203 weirdAltitude = (-entry['elev'] - 6371010) / desiredHeight gevrplace.places.savedPlace.location.picParams.weirdAltitude = weirdAltitude gevrplace.places.savedPlace.location.picParams.pitch = 0.00692561878283 gevrplace.places.savedPlace.location.heading = entry['heading'] gevrplace.places.savedPlace.location.viewMode = gevrplace_pb2.GEVRPlace.Places.Place.Location.EARTH_BELOW gevrplace.places.savedPlace.location.elevation = desiredHeight gevrplace.places.savedPlace.location.unknown3 = gevrplace_pb2.GEVRPlace.Places.Place.Location.UNKNOWN0 gevrplace.places.savedPlace.time.year = 2015 gevrplace.places.savedPlace.time.month = 8 gevrplace.places.savedPlace.time.day = 25 gevrplace.places.savedPlace.time.hour = 5 gevrplace.places.savedPlace.time.minute = 53 gevrplace.places.savedPlace.time.second = 23 ENCODED = base64.b64encode( gevrplace.SerializeToString()).decode().rstrip("=") xmpfile = XMPFiles(file_path=newFile.name, open_forupdate=True, open_usesmarthandler=True) xmp = xmpfile.get_xmp() xmp.register_namespace("http://ns.google.com/photos/1.0/earthvr/", "EarthVR") xmp.set_property(xmp.get_namespace_for_prefix("EarthVR"), "SerializedMetadata", ENCODED) xmp.set_property(xmp.get_namespace_for_prefix("EarthVR"), "Version", '1.0') xmpfile.put_xmp(xmp) xmpfile.close_file() return points
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 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