示例#1
0
    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")
示例#2
0
文件: matchup.py 项目: inogs/bit.sea
    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.')
示例#5
0
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
示例#6
0
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_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 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()
示例#9
0
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()
示例#10
0
    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()
示例#11
0
 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
示例#12
0
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 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()
示例#15
0
文件: im2sim.py 项目: IanHawke/im2sim
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
示例#16
0
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()
示例#17
0
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()
示例#18
0
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
示例#19
0
    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)
示例#20
0
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_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_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_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)
示例#26
0
    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)
示例#27
0
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
示例#28
0
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()
示例#30
0
文件: dcfile.py 项目: datadavev/ren
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')
示例#31
0
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()
示例#32
0
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()
示例#33
0
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
示例#34
0
    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