Esempio n. 1
0
def test_save_as_saves_as_new_file_with_new_info():
    if os.path.isfile('fixtures/deleteme.jpg'):  # pragma: no cover
        os.unlink('fixtures/deleteme.jpg')

    new_headline = b'test headline %d' % random.randint(0, 100)
    info = IPTCInfo('fixtures/Lenna.jpg')
    info['headline'] = new_headline
    info.save_as('fixtures/deleteme.jpg')

    info2 = IPTCInfo('fixtures/deleteme.jpg')

    assert info2['headline'] == new_headline
Esempio n. 2
0
def process_image(ifile:str, siteconfig, ofile:str=None):
    '''resize an image and return the output file name and the exif and iptc meta data'''
    try:
        size = siteconfig.get('resize')
        site_copyright_notice = siteconfig.get('copyright_notice')

        im  = Image.open(ifile)
        im_xif = im.info.get('exif')
        im_iptc = retrieve_copyright_notice(ifile)

        dest = ofile if size and ofile else ifile #Target the input file if the output file is not provided
        
        # Image resizing with exif preservation
        if size:
            im2 = im.resize(size)

            params = dict(exif=im_xif) if im_xif else dict()   
            im2.save(dest, **params)

        # IPTC data rewriting. IPTC are lost during the resize operation. We have to put them back manually
        # If the inputfile contains a copyright notice, then use it instead of the siteconfig value
        im_iptc['copyright notice'] = im_iptc.get('copyright notice', site_copyright_notice)

        if im_iptc or site_copyright_notice:
            iptc = IPTCInfo(dest)

            for key in im_iptc:
                iptc[key] = im_iptc[key]
            iptc.save()

        return (dest, im_xif, im_iptc)
    except Exception as e:
        printfailure('could not process image ', ifile, ' traceback ', str(e))
        return (ifile, None, None)
Esempio n. 3
0
 def __init__(self, path):
     self.path = path
     self.exif = self.extract_exif(path)
     self.iptc = IPTCInfo(path)
     latitude, longitude = GPS(path).decimal_coordinates
     self.latitude = latitude
     self.longitude = longitude
Esempio n. 4
0
def get_imageinfo(filepath: str) -> dict:
    """
    Return EXIF and IPTC information found from image file in a dictionary.
    """
    info = {}
    info["exif"] = exif = read_exif(filepath)
    info["gps"] = gps = parse_gps(exif)
    info.update(parse_datetime(exif, tag_name="EXIF DateTimeOriginal",
                               gps=gps))
    if "lat" in gps:  # Backwards compatibility
        info["lat"], info["lon"] = gps["lat"], gps["lon"]
    info["iptc"] = iptc = IPTCInfo(filepath, force=True)
    try:
        if iptc.data["caption/abstract"]:
            info["caption"] = iptc.data["caption/abstract"]
        if iptc.data["object name"]:
            info["title"] = iptc.data["object name"]
        if iptc.data["keywords"]:
            kw_str = ",".join(iptc.data["keywords"])
            info["keywords"] = kw_str
            info["tags"] = iptc.data["keywords"]
        for key in info:  # Convert all str values to unicode
            if isinstance(info[key], str):
                info[key] = str(info[key], guess_encoding(info[key]))
    except AttributeError:
        pass
    with open(str(filepath), "rb") as f:
        im = Image.open(f)
        info["width"], info["height"] = im.size
        del im
    return info
Esempio n. 5
0
def test_getitem_can_read_info():
    info = IPTCInfo('fixtures/Lenna.jpg')

    assert len(info) >= 4
    assert info['keywords'] == [b'lenna', b'test']
    assert info['supplemental category'] == [b'supplemental category']
    assert info['caption/abstract'] == b'I am a caption'
Esempio n. 6
0
def retrieve_copyright_notice(fn:str) -> dict:
    '''Retrieves the copyright notice from the input file
    Returns
    -------
    Tuple (copyright notice, description)
    '''
    info = IPTCInfo(fn)
    return {
        key: info[key]
        for key in c_datasets.values() if info[key]
    }
Esempio n. 7
0
def test_save_as_saves_as_new_file_with_info():
    if os.path.isfile('fixtures/deleteme.jpg'):  # pragma: no cover
        os.unlink('fixtures/deleteme.jpg')

    info = IPTCInfo('fixtures/Lenna.jpg')
    info.save_as('fixtures/deleteme.jpg')

    info2 = IPTCInfo('fixtures/deleteme.jpg')

    # The files won't be byte for byte exact, so filecmp won't work
    assert info._data == info2._data
    with open('fixtures/Lenna.jpg', 'rb') as fh, open('fixtures/deleteme.jpg',
                                                      'rb') as fh2:
        start, end, adobe = jpeg_collect_file_parts(fh)
        start2, end2, adobe2 = jpeg_collect_file_parts(fh2)

    # But we can compare each section
    assert start == start2
    assert end == end2
    assert adobe == adobe2
Esempio n. 8
0
def process_file(filename):
    """ Want to return: [filename, caption, [tags]] """

    info = IPTCInfo(filename)
    if len(info.data) < 4: raise Exception(info.error)

    keywords = []
    for keyword in info.keywords:
        keywords.append(keyword.decode("utf-8"))

    return [filename, info.data["caption/abstract"], keywords]
Esempio n. 9
0
def get_date(DATADIR_RAW, DATADIR_RAW_NEW):
    '''Function wich takes as input path of dirs. in those dirs the function will irreterate throug all jpg, extract a date from their meta date and it a IPTC protocol'''

    # get the image name from the dir DATADIR_RAW
    for img in os.listdir(DATADIR_RAW):
        image_path = os.path.join(DATADIR_RAW, img)
        info = IPTCInfo(image_path, force=True)
        print(img)

        # Open the image and access the metadate. Use regex to extract date:
        image = Image.open(image_path)
        txt = str(image.info['exif'])  # exif are mostly JPEG
        r = '[\d]{4}:[\d]{2}:[\d]{2}'  # format yyyy:mm:dd
        date = re.search(r, txt).group().replace(':', '')
        print(f'date of picture: {date}')

        # Force open the IPTC protocol to insert date
        info = IPTCInfo(image_path, force=True)
        print(f"info before: {info['date created']}"
              )  #Before. Shows wheter or not the entry was empty before
        info['date created'] = date
        print(f"info after: {info['date created']}"
              )  # after. Shows the date extracted from the meta data
        print('\n')

        # Create the new dir DATADIR_RAW_NEW if it does not already exist
        if not os.path.exists(DATADIR_RAW_NEW):
            os.makedirs(DATADIR_RAW_NEW)

        # Create the new path for the image
        new_path = os.path.join(DATADIR_RAW_NEW, 'new' + img)

        # If that image is already in the path, delete it.
        if os.path.exists(DATADIR_RAW_NEW):
            try:
                os.remove(new_path)
            except:
                pass

        # Save new image.
        info.save_as(new_path)
Esempio n. 10
0
def make_big_groups(photo_filenames):
    """Group images by keyword
    """
    grouped = {}
    for photo_filename in photo_filenames:
        info = IPTCInfo(photo_filename)
        for x in info["keywords"]:
            x = x.decode("utf-8")
            if x not in grouped:
                grouped[x] = []
            grouped[x].append(photo_filename)
    return grouped
Esempio n. 11
0
def update_index(filepath, filename):
    info = IPTCInfo(filepath + "/" + filename, force=True)
    keywords = []
    master_index_trie = load_obj("master_index_trie")
    pp(master_index_trie)

    for item in info["keywords"]:
        keywords.append(item.decode("utf-8"))

    for item in keywords:
        associated_pics = trie.find_prefix(master_index_trie, item)[2]
        if type(associated_pics) == list and filename not in associated_pics:
            trie.add_value(master_index_trie, item, filename)
            save_obj(master_index_trie, "master_index_trie")
Esempio n. 12
0
def get_img_data(sfile):
    try:
        info = IPTCInfo(sfile)
    except:
        logging.ERROR("Could not open file: %s" % sfile)

    data = dict()

    data["path"] = sfile
    data["filename"] = os.path.basename(sfile)

    title = info["object name"] or info["headline"]
    if title:
        data["title"] = title.decode(ENCODING)
    desc = info["caption/abstract"]
    if desc:
        data["description"] = desc.decode(ENCODING)
    date = info["date created"]
    if date:
        date_obj = datetime.datetime.strptime(date.decode(ENCODING), '%Y%m%d')
        data["date"] = date_obj
    data["keywords"] = []
    if info["keywords"]:
        for key in info["keywords"]:
            data["keywords"].append(key.decode(ENCODING))

    # exif
    exif = get_exif(sfile)
    for tag in exif.keys():
        value = str(exif[tag])
        if tag == "Image Model":
            data["model"] = value
        if tag == "EXIF ExposureTime":
            data["shutter"] = value
        if tag == "EXIF FocalLength":
            data["focal"] = value
        if tag == "EXIF FNumber":
            data["aperture"] = str(parse_fstop(value))
        if tag == "EXIF ISOSpeedRatings":
            data["iso"] = value
        if tag == "EXIF LensModel":
            data["lens"] = value

    data["shortcode"] = get_shortcode(data)

    return data
Esempio n. 13
0
def process_file(filepath, random_replace=False, verbose=False):
    img_type = imghdr.what(filepath)

    if img_type is None:
        if verbose:
            print("Skipping).")
        return

    if verbose:
        print(img_type, end='). ')

    info = IPTCInfo(filepath, force=True)

    special_instructions = info['special instructions']
    if special_instructions is None:
        if verbose:
            print("FBMD not found")
        return

    fbmd_index = special_instructions.find(b'FBMD')
    if fbmd_index < 0:
        if verbose:
            print("FBMD not found")
        return

    length_hex = special_instructions[fbmd_index + 6:fbmd_index + 6 + 4]
    length = int(length_hex, 16)

    info['special instructions'] = update_instructions(special_instructions,
                                                       fbmd_index,
                                                       length,
                                                       random=random_replace)

    if verbose:
        print(special_instructions[fbmd_index:fbmd_index + 6 + 4 +
                                   (length + 1) * 8])

    info.save()
    os.remove(filepath + "~")