Beispiel #1
1
 def test_transplant_m(self):
     """'transplant' on memory.
     """
     o = io.BytesIO()
     piexif.transplant(I1, I2, o)
     self.assertEqual(piexif.load(I1), piexif.load(o.getvalue()))
     Image.open(o).close()
def test_piexif( input_file_name, output_file_name, args ):
    """
    Tests Exif manipulation using Piexif performing JPEG I/O with buffered
    reads and writes.

    Takes 3 arguments:

      input_file_name  - Path of input JPEG file.
      output_file_name - Path of output JPEG file.
      args             - Dictionary of arguments provided to the test.  This
                         is unused.

    Returns nothing.
    """

    import piexif

    jpeg_data = open( input_file_name, "rb" ).read()
    o         = io.BytesIO()

    # use piexif to extract our Exif data and insert it back into the raw JPEG
    # byte stream.
    exif_dict = piexif.load( input_file_name )
    exif_dict['GPS'][2] = ((1, 1), (2, 1), (3, 1))
    exif_dict['GPS'][4] = ((4, 1), (5, 1), (6, 1))
    exif_bytes = piexif.dump( exif_dict )

    piexif.insert( exif_bytes, jpeg_data, o )

    with open( output_file_name, "wb" ) as file:
        file.write( o.getvalue() )

    munged_jpeg_data  = open( output_file_name, "rb" ).read()
    munged_exif_dict  = piexif.load( output_file_name )
    munged_exif_bytes = piexif.dump( munged_exif_dict )
Beispiel #3
0
    def test_load_fail(self):
        with self.assertRaises(ValueError):
            exif = piexif.load(os.path.join("tests", "images", "note.txt"))

        with self.assertRaises(ValueError):
            exif = piexif.load(os.path.join("tests", "images", "notjpeg.jpg"))

        with self.assertRaises(ValueError):
            exif = piexif.load(os.path.join("Oh", "My", "God"))
Beispiel #4
0
    def test_load_tif(self):
        exif = piexif.load(INPUT_FILE_TIF)
        zeroth_ifd = exif["0th"]
        exif_bytes = piexif.dump({"0th":zeroth_ifd})

        im = Image.new("RGBA", (8, 8))
        o = io.BytesIO()
        im.save(o, format="jpeg", exif=exif_bytes)
        im.close()
        exif2 = piexif.load(o.getvalue())
        zeroth_ifd2 = exif2["0th"]
        self.assertDictEqual(zeroth_ifd, zeroth_ifd2)
Beispiel #5
0
    def test_transplant(self):
        piexif.transplant(INPUT_FILE1, INPUT_FILE_PEN, "transplant.jpg")
        i = Image.open("transplant.jpg")
        i.close()
        exif_src = piexif.load(INPUT_FILE1)
        img_src = piexif.load(INPUT_FILE_PEN)
        generated = piexif.load("transplant.jpg")
        self.assertEqual(exif_src, generated)
        self.assertNotEqual(img_src, generated)

        piexif.transplant(INPUT_FILE1, "transplant.jpg")
        self.assertEqual(piexif.load(INPUT_FILE1),
                         piexif.load("transplant.jpg"))
        os.remove("transplant.jpg")
Beispiel #6
0
    def test_remove(self):
        piexif.remove(INPUT_FILE1, "remove.jpg")
        exif_dict = piexif.load("remove.jpg")
        none_dict = {"0th":{},
                     "Exif":{},
                     "GPS":{},
                     "Interop":{},
                     "1st":{},
                     "thumbnail":None}
        self.assertEqual(exif_dict, none_dict)

        piexif.remove("remove.jpg")
        exif_dict = piexif.load("remove.jpg")
        self.assertEqual(exif_dict, none_dict)
        os.remove("remove.jpg")
Beispiel #7
0
Datei: utils.py Projekt: Josca/im
def imread(filepath):
    image = Image.open(filepath)
    try:
        exf = piexif.load(image.info['exif'])
    except:
        exf = None
    return image, exf
Beispiel #8
0
def get_exif_datetimeorig_tag(fname):
    """
    Returns the EXIF Tag 36867 (DateTimeOriginal) from a file

    The return string will have the format 'YYYY:MM:DD HH:MM:SS' or 
    if no EXIF tag is found or the file is not valid or doesn't exist,
    an exception will be thrown

    :param fname:   Name of file to read EXIF tag from
    :returns:       EXIF tag in specified format

    :Example:

        >>> import fileops
        >>> print fileops.get_exif_datetimeorig_tag("IMG_1234.JPG")
        '2013:09:30 15:21:42'
    """

    try:
        exif_dict = piexif.load(fname)

    except ValueError:
        raise EXIFTagError, "Not a valid picture file"

    else:

        if exif_dict['Exif']:
            try:
                date_string = exif_dict['Exif'][36867]
            except KeyError:
                raise EXIFTagError, "No DateTimeOriginal EXIF Tag found"
            else:
                return date_string
        else:
            raise EXIFTagError, "No EXIF information found"
Beispiel #9
0
def manipulate_exif(img, settings):

    try:
        exif = piexif.load(img.info['exif'])
    except Exception:
        logger.debug('EXIF information not found')
        exif = {}

    if settings['PHOTO_EXIF_AUTOROTATE']:
        img, exif = rotate_image(img, exif)

    if settings['PHOTO_EXIF_REMOVE_GPS']:
        exif.pop('GPS')

    if settings['PHOTO_EXIF_COPYRIGHT']:

        # We want to be minimally destructive to any preset exif author or copyright information.
        # If there is copyright or author information prefer that over everything else.
        if not exif['0th'].get(piexif.ImageIFD.Artist):
            exif['0th'][piexif.ImageIFD.Artist] = settings['PHOTO_EXIF_COPYRIGHT_AUTHOR']
            author = settings['PHOTO_EXIF_COPYRIGHT_AUTHOR']

        if not exif['0th'].get(piexif.ImageIFD.Copyright):
            license = build_license(settings['PHOTO_EXIF_COPYRIGHT'], author)
            exif['0th'][piexif.ImageIFD.Copyright] = license

    return (img, piexif.dump(exif))
Beispiel #10
0
def _get_exif_orientation(exif):
    """
    Return the orientation value for the given Image object, or None if the
    value is not set.
    """
    exif_dict = piexif.load(exif)
    return exif_dict['0th'].get(piexif.ImageIFD.Orientation)
Beispiel #11
0
def setgeoimage(data,lat,lon,imagedescription="",usercomment="",dt=None):

        exif_dict = piexif.load(data)

        #for ifd in ("0th", "Exif", "GPS", "1st"):
        #    for tag in exif_dict[ifd]:
        #        print tag
        #        print(piexif.TAGS[ifd][tag]["name"], exif_dict[ifd][tag])
        #
        #lat,lon=get_geo(exif_dict)
        #print "lat lon",lat,lon

        if dt is None:
             exif_dict["0th"][piexif.ImageIFD.DateTime]=datetime.utcnow().strftime("%Y:%m:%d %H:%M:%S")
        else:
             exif_dict["0th"][piexif.ImageIFD.DateTime]=dt.strftime("%Y:%m:%d %H:%M:%S")
        set_geo(exif_dict, lat, lon)
        exif_dict["Exif"][piexif.ExifIFD.UserComment]=chr(0x55)+chr(0x4E)+chr(0x49)+chr(0x43)+chr(0x4F)+chr(0x44)+chr(0x45)+chr(0x00)+usercomment
        exif_dict["0th"][piexif.ImageIFD.ImageDescription]=imagedescription
        exif_bytes = piexif.dump(exif_dict)

        new_data=io.BytesIO(data)
        piexif.insert(exif_bytes, data, new_data)

        return new_data.getvalue()
Beispiel #12
0
def normalize_image_orientation(img_file):
    """Reads orientation tag from the exif data attached to a JPEG
    image. Returns the image rotated to normal orientation and with
    corresponding normal exif orientation tag.

    Note: horizontal (normal) exif value = 1
    """

    ### Open image and read orientation tag
    im = Image.open(img_file)
    exif_dict = piexif.load(im.info["exif"])
    orientation = exif_dict["0th"][piexif.ImageIFD.Orientation]
    print(orientation)

    ## Rotate image
    im = rotate_image_to_normal(im, orientation)

    ## Create new exif dict with base orientation value of 1
    exif_dict["0th"][piexif.ImageIFD.Orientation] = 1
    exif_bytes = piexif.dump(exif_dict)

    ## Return file in a buffer
    buf = BytesIO()
    im.save(buf, "jpeg", exif=exif_bytes)
    buf.seek(0)
    return(buf)
def test_piexif_with_pil( input_file_name, output_file_name, args ):
    """
    Tests Exif manipulation using Piexif performing JPEG I/O with PIL.
    Note that PIL performs image decompression and recompression which
    will likely alter the contents of image.

    Takes 3 arguments:

      input_file_name  - Path of input JPEG file.
      output_file_name - Path of output JPEG file.
      args             - Dictionary of arguments provided to the test.  This
                         may contain a "quality" key that specifies a
                         quality parameter suitable for use when saving a JPEG
                         with PIL.

    Returns nothing.
    """
    import piexif
    from PIL import Image

    # use piexif to extract our Exif data.
    exif_dict = piexif.load( input_file_name )
    exif_dict['GPS'][2] = ((1, 1), (2, 1), (3, 1))
    exif_dict['GPS'][4] = ((4, 1), (5, 1), (6, 1))
    exif_bytes = piexif.dump( exif_dict )

    # use PIL to specify raw Exif data when saving.
    #
    # NOTE: this will reencode the file that has been opened which is likely
    #       not what a user wants.
    im = Image.open( input_file_name )
    im.save( output_file_name, exif=exif_bytes, **args )
Beispiel #14
0
def get_exif_tags(image_data):
    try:
        def decode_tag(tag):
            if type(tag) == bytes:
                tag = tag.rstrip(b'\x00')
                try:
                    return tag.decode('utf-8')
                except UnicodeDecodeError:
                    return tag.decode('ascii', 'ignore')
            else:
                return tag

        exif_dict = piexif.load(image_data)
        return {
            piexif.TAGS[ifd][tag]["name"]: decode_tag(exif_dict[ifd][tag])
            for ifd in ["0th", "1st", "Exif", "GPS"]
            for tag in exif_dict[ifd]
            if tag != piexif.ExifIFD.MakerNote # Exclude proprietary MakerNote tag
        }
    except Exception:
        # Don't let any exceptions bubble (ignore exif data silently), but log a warning
        logger.warning(
            "Kunne ikke parse exif data",
            exc_info=sys.exc_info(),
        )
def create_duplicateOLD(source, target, batch, frame):
    if config['overlay-text'] or config['resize']:
        img = Image.open(source)
        exif_bytes = None
        if config['resize']:
            img = img.resize(
                (config['resize_width'], config['resize_height']),
                Image.ANTIALIAS)
        if config['write_exif']:
            exif_dict = piexif.load(img.info['exif'])
            # from pprint import pprint
            # pprint(exif_dict)
            exif_dict["0th"][piexif.ImageIFD.Orientation] = 4
            exif_bytes = piexif.dump(exif_dict)
        if config['overlay-text']:
            # text overlay
            if config['image_format'] == "XXXX_XX":
                text = "%04d-%02d" % (batch, frame)
            else:
                text = "%04d" % (batch)
            draw = ImageDraw.Draw(img)
            draw.text(
                (60, 60),
                text,
                (255, 14, 179),
                font=config['font']
            )
        if config['write_exif']:
            img.save(target, quality=config['image-quality'], exif=exif_bytes)
        else:
            img.save(target, quality=config['image-quality'])
    else:
        shutil.copy2(source, target)
    time.sleep(config['delay_between_frames'])
def add_gps_tags(path: str, gps_tags: {str: any}):
    """This method will add gps tags to the photo found at path"""
    exif_dict = piexif.load(path)
    for tag, tag_value in gps_tags.items():
        exif_dict["GPS"][tag] = tag_value
    exif_bytes = piexif.dump(exif_dict)
    piexif.insert(exif_bytes, path)
Beispiel #17
0
 def test_load_m(self):
     """'load' on memory.
     """
     exif = piexif.load(I1)
     e = load_exif_by_PIL(INPUT_FILE1)
     print("********************\n\n" + INPUT_FILE1 + "\n")
     self._compare_piexifDict_PILDict(exif, e)
    def _rotate_exif_image(self, im):
        if VERSION_AUTOROTATE_EXIF and 'exif' in im.info:
            import piexif

            x, y = im.size
            try:
                e_dict = piexif.load(im.info['exif'])
                if piexif.ImageIFD.Orientation in e_dict['0th']:
                    orientation = e_dict['0th'].pop(piexif.ImageIFD.Orientation)
                    if orientation == 2:
                        im = im.transpose(Image.FLIP_LEFT_RIGHT)
                    elif orientation == 3:
                        im = im.rotate(180)
                    elif orientation == 4:
                        im = im.rotate(180).transpose(Image.FLIP_LEFT_RIGHT)
                    elif orientation == 5:
                        im = im.rotate(-90, expand=1).transpose(Image.FLIP_LEFT_RIGHT)
                        im.size = (y, x)
                    elif orientation == 6:
                        im = im.rotate(-90, expand=1)
                        im.size = (y, x)
                    elif orientation == 7:
                        im = im.rotate(90, expand=1).transpose(Image.FLIP_LEFT_RIGHT)
                        im.size = (y, x)
                    elif orientation == 8:
                        im = im.rotate(90, expand=1)
                        im.size = (y, x)
            except:
                pass
        return im
Beispiel #19
0
 def test_load(self):
     files = glob.glob(os.path.join("tests", "images", "r_*.jpg"))
     for input_file in files:
         exif = piexif.load(input_file)
         e = load_exif_by_PIL(input_file)
         print("********************\n" + input_file + "\n")
         self._compare_piexifDict_PILDict(exif, e, p=False)
Beispiel #20
0
    def test_dump_and_load2(self):
        thumbnail_io = io.BytesIO()
        thumb = Image.open(INPUT_FILE2)
        thumb.thumbnail((40, 40))
        thumb.save(thumbnail_io, "JPEG")
        thumb.close()
        thumb_data = thumbnail_io.getvalue()
        exif_dict = {"0th":ZEROTH_IFD,
                     "Exif":EXIF_IFD,
                     "GPS":GPS_IFD,
                     "Interop":INTEROP_IFD,
                     "1st":FIRST_IFD,
                     "thumbnail":thumb_data}
        exif_bytes = piexif.dump(exif_dict)
        im = Image.new("RGBA", (80, 80))

        o = io.BytesIO()
        im.save(o, format="jpeg", exif=exif_bytes)
        im.close()
        o.seek(0)
        exif = piexif.load(o.getvalue())
        exif["0th"].pop(ImageIFD.ExifTag) # pointer to exif IFD
        exif["0th"].pop(ImageIFD.GPSTag) # pointer to GPS IFD
        exif["Exif"].pop(ExifIFD.InteroperabilityTag)
        self.assertDictEqual(ZEROTH_IFD, exif["0th"])
        self.assertDictEqual(EXIF_IFD, exif["Exif"])
        self.assertDictEqual(GPS_IFD, exif["GPS"])
        self.assertDictEqual(INTEROP_IFD, exif["Interop"])
        exif["1st"].pop(513) # pointer to exif IFD
        exif["1st"].pop(514) # pointer to GPS IFD
        self.assertDictEqual(FIRST_IFD, exif["1st"])
        Image.open(io.BytesIO(exif["thumbnail"])).close()
Beispiel #21
0
 def __init__(self, location: Path):
     self.location = location
     metadata_store = MetadataFile(self.location.with_name('_metadata.yaml'))
     self.metadata = metadata_store.get_section(self.location.stem)
     info = piexif.load(str(self.location))
     self.exif = info['Exif']
     self.zeroth = info['0th']
Beispiel #22
0
    def test_rotation(self):

        tu = TestUtils()
        assert tu.is_env_clean(tu.conf['lycheepath']), "env not clean"
        # load 1 album with same photo under different name
        tu.load_photoset("rotation")
        # launch lycheesync
        src = tu.conf['testphotopath']
        lych = tu.conf['lycheepath']
        conf = tu.conf['conf']

        # run
        runner = CliRunner()
        result = runner.invoke(main, [src, lych, conf, '-v'])
        # no crash
        assert result.exit_code == 0, "process result is ok"

        photos = tu.get_photos(tu.get_album_id('rotation'))
        for p in photos:
            # rotation tag is gone
            pfullpath = os.path.join(lych, "uploads", "big", p['url'])
            img = Image.open(pfullpath)
            assert "exif" in img.info, "Pas d'info exif"
            exif_dict = piexif.load(img.info["exif"])
            assert exif_dict["0th"][piexif.ImageIFD.Orientation] == 1, "Exif rotation should be 1"
            img.close()
Beispiel #23
0
def run(filepath):

    try:
        exifdata = piexif.load(filepath)
    except piexif.InvalidImageDataError:
        return {}

    # How to present?
    # exifdata['GPS'][piexif.GPSIFD.GPSLatitudeRef],  # N
    # exifdata['GPS'][piexif.GPSIFD.GPSLatitude],     # ((59, 1), (50, 1), (1111, 100))
    # exifdata['GPS'][piexif.GPSIFD.GPSLongitudeRef], # E
    # exifdata['GPS'][piexif.GPSIFD.GPSLongitude],    # (10, 1), (50, 1), (3000, 100))
    gpslatlon = None

    return {
        'ImageLength': exifdata['0th'].get(piexif.ImageIFD.ImageLength, b''),
        'ImageWidth': exifdata['0th'].get(piexif.ImageIFD.ImageWidth, b''),
        'Make': exifdata['0th'].get(piexif.ImageIFD.Make, b'').decode('utf-8'),
        'Model': exifdata['0th'].get(piexif.ImageIFD.Model, b'').decode('utf-8'),
        'Orientation': exifdata['0th'].get(piexif.ImageIFD.Orientation, b''),

        'Flash': exifdata['Exif'].get(piexif.ExifIFD.Flash, b''),

        'GPSAltitudeRef': exifdata['GPS'].get(piexif.GPSIFD.GPSAltitudeRef, b''),
        'GPSLatLon': gpslatlon,
    }
Beispiel #24
0
def hide(input_image_file, img_enc, secret_message = None, secret_file = None):
    """
    Hide a message (string) in an image.
    """
    from zlib import compress
    from base64 import b64encode

    if secret_file != None:
        with open(secret_file, "r") as f:
            secret_message = f.read()

    try:
        text = compress(b64encode(bytes(secret_message, "utf-8")))
    except:
        text = compress(b64encode(secret_message))

    img = Image.open(input_image_file)
    if "exif" in img.info:
        exif_dict = piexif.load(img.info["exif"])
    else:
        exif_dict = {}
        exif_dict["0th"] = {}
    exif_dict["0th"][piexif.ImageIFD.ImageDescription] = text
    exif_bytes = piexif.dump(exif_dict)
    img.save(img_enc, exif=exif_bytes)
    img.close()
    return img
Beispiel #25
0
    def get_data(self):
        """
        Get picture exif'GPS information
        :return:
        """
        file_dialog = QtGui.QFileDialog()
        file_name = file_dialog.getOpenFileName()
        # self.line_edit set text
        self.line_edit.setText(str(file_name))
        # load picture and get exif data as dict
        exif_data = piexif.load(str(file_name))

        if exif_data['GPS']:
            print exif_data['GPS']
            for key, value in exif_data['GPS'].items():
                print key, value
            try:
                self.latitude = self.d2l(exif_data['GPS'].get(7))
                self.longitude = self.d2l(exif_data['GPS'].get(7))
                print 'latitude: %s' % self.latitude
                print 'longitude: %s' % self.longitude
            except:
                QtGui.QMessageBox.information(self, 'Message', 'Get latitude and longitude error!')
        else:
            QtGui.QMessageBox.information(self, 'Message', 'This picture has not GPS information!')
Beispiel #26
0
    def download_image_with_retry(image, bucket, tmp_file, tmp_file_index, zip_archive, file_count, tries=5):
        """
        Tries to download an image from S3, and if an SSLError occurs, resets the boto connection and retries the
        download. This was implemented because we experienced this error occasionally for large album downloads.
        The idea was originally to use funcy[1] with the @retry decorator, but we discovered that we need to change
        state on error (i.e. reset the boto connection), which AFAIK couldn't be done with funcy; hence this custom
        implementation.
        [1] See https://github.com/Suor/funcy and
            http://hackflow.com/blog/2014/06/22/why-every-language-needs-its-underscore/
        """
        try:
            image_key = bucket.get_key("%s/%s.%s" % (settings.AWS_S3_FOLDERS['imagearchive'], image.key, image.extension))
            image_data = image_key.get_contents_as_string()
            pil_image = PIL.Image.open(BytesIO(image_data))
            image_data_buffer = BytesIO()

            # Write relevant exif data
            try:
                exif = piexif.load(image_data)
                exif['0th'][piexif.ImageIFD.ImageDescription] = image.description
                exif['0th'][piexif.ImageIFD.Artist] = image.photographer
                exif['0th'][piexif.ImageIFD.Copyright] = image.licence
                pil_image.save(image_data_buffer, standardize_extension(image.extension), exif=piexif.dump(exif))
            except ValueError:
                # piexiv will throw ValueError if the file type isn't JPEG or the file contains invalid exif data; if so
                # skip writing exif
                pil_image.save(image_data_buffer, standardize_extension(image.extension))

            # And add the modified image to the zip archive
            if image.photographer == '':
                image_filename = '%s-%s.%s' % (image_set_name, file_count, image.extension)
            else:
                image_filename = '%s-%s-%s.%s' % (image_set_name, file_count, image.photographer, image.extension)

            # Rather than encoding for a specific platform and yielding encoding errors on other platforms, use the
            # ascii encoder to filter out non-ascii chars
            image_filename = image_filename.encode('ascii', 'ignore').decode()

            zip_archive.writestr(image_filename, image_data_buffer.getvalue())

            # Rewind the memory file back, read the written data, and yield it to our response,
            # while we'll go fetch the next file from S3
            next_index = tmp_file.tell()
            tmp_file.seek(tmp_file_index)
            return next_index, tmp_file.read()
        except Exception:
            logger.warning(
                "Feil ved albumnedlasting (prøver igjen automatisk)",
                exc_info=sys.exc_info(),
                extra={'request': request}
            )

            if tries <= 0:
                raise

            # Reset the conncetion and try again
            conn = boto.connect_s3(settings.AWS_ACCESS_KEY_ID, settings.AWS_SECRET_ACCESS_KEY)
            bucket = conn.get_bucket(settings.AWS_S3_BUCKET)
            return download_image_with_retry(image, bucket, tmp_file, tmp_file_index, zip_archive, file_count, tries=tries-1)
Beispiel #27
0
    def resize_image(self, src, dst, max_size, bigger_panoramas=True, preserve_exif_data=False, exif_whitelist={}):
        """Make a copy of the image in the requested size."""
        if not Image or os.path.splitext(src)[1] in ['.svg', '.svgz']:
            self.resize_svg(src, dst, max_size, bigger_panoramas)
            return
        im = Image.open(src)

        if hasattr(im, 'n_frames') and im.n_frames > 1:
            # Animated gif, leave as-is
            utils.copy_file(src, dst)
            return

        size = w, h = im.size
        if w > max_size or h > max_size:
            size = max_size, max_size

            # Panoramas get larger thumbnails because they look *awful*
            if bigger_panoramas and w > 2 * h:
                size = min(w, max_size * 4), min(w, max_size * 4)

        try:
            exif = piexif.load(im.info["exif"])
        except KeyError:
            exif = None
        # Inside this if, we can manipulate exif as much as
        # we want/need and it will be preserved if required
        if exif is not None:
            # Rotate according to EXIF
            value = exif['0th'].get(piexif.ImageIFD.Orientation, 1)
            if value in (3, 4):
                im = im.transpose(Image.ROTATE_180)
            elif value in (5, 6):
                im = im.transpose(Image.ROTATE_270)
            elif value in (7, 8):
                im = im.transpose(Image.ROTATE_90)
            if value in (2, 4, 5, 7):
                im = im.transpose(Image.FLIP_LEFT_RIGHT)
            exif['0th'][piexif.ImageIFD.Orientation] = 1

        try:
            im.thumbnail(size, Image.ANTIALIAS)
            if exif is not None and preserve_exif_data:
                # Put right size in EXIF data
                w, h = im.size
                if '0th' in exif:
                    exif["0th"][piexif.ImageIFD.ImageWidth] = w
                    exif["0th"][piexif.ImageIFD.ImageLength] = h
                if 'Exif' in exif:
                    exif["Exif"][piexif.ExifIFD.PixelXDimension] = w
                    exif["Exif"][piexif.ExifIFD.PixelYDimension] = h
                # Filter EXIF data as required
                exif = self.filter_exif(exif, exif_whitelist)
                im.save(dst, exif=piexif.dump(exif))
            else:
                im.save(dst)
        except Exception as e:
            self.logger.warn("Can't process {0}, using original "
                             "image! ({1})".format(src, e))
            utils.copy_file(src, dst)
Beispiel #28
0
def _update_exif_orientation(exif, orientation):
    """
    Given an exif value and an integer value 1-8, reflecting a valid value for
    the exif orientation, return a new exif with the orientation set.
    """
    exif_dict = piexif.load(exif)
    if orientation:
        exif_dict['0th'][piexif.ImageIFD.Orientation] = orientation
    return piexif.dump(exif_dict)
Beispiel #29
0
 def test_no_exif_load(self):
     exif_dict = piexif.load(NOEXIF_FILE)
     none_dict = {"0th":{},
                  "Exif":{},
                  "GPS":{},
                  "Interop":{},
                  "1st":{},
                  "thumbnail":None}
     self.assertEqual(exif_dict, none_dict)
Beispiel #30
0
import sys
import json
import csv
from pathlib import Path

import piexif


try:
    csv_path = sys.argv[-2]
    root = sys.argv[-1]
except Exception:
    print('Usage: python addmask.py <csv> <root>')
    exit()

labels = {}
with open(csv_path) as fp:
    for row in csv.DictReader(fp):
        label = [int(v) for v in row[' EncodedPixels'].split(' ') if v != '']
        labels.setdefault(row['ImageId'], []).append(label)

for p in Path(root).glob('*.jpg'):
    if p.stem in labels:
        exif_dict = piexif.load(str(p))
        exif = json.loads(exif_dict["Exif"][piexif.ExifIFD.MakerNote].decode("ascii"))
        exif["Masks"] = labels[p.stem]
        exif_dict["Exif"][piexif.ExifIFD.MakerNote] = json.dumps(exif).encode("ascii")
        piexif.insert(piexif.dump(exif_dict), str(p))
Beispiel #31
0
def extract_exif_bytes(pil_original_image):
    try:
        exif_dict = piexif.load(pil_original_image.info["exif"])
        return piexif.dump(exif_dict)
    except KeyError:
        return None
Beispiel #32
0
def set_file_mod_time_from_jpeg_time(file):
    exif_dict = piexif.load(file)
    dt = datetime.strptime(exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal], "%Y:%m:%d %H:%M:%S")
    timestamp = (dt - datetime(1970, 1, 1)).total_seconds()
    os.utime(file, (timestamp, timestamp))
Beispiel #33
0
def optimize_jpg(t: Task) -> TaskResult:
    """ Try to reduce file size of a JPG image.

    Expects a Task object containing all the parameters for the image processing.

    If file reduction is successful, this function will replace the original
    file with the optimized version and return some report data (file path,
    image format, image color mode, original file size, resulting file size,
    and resulting status of the optimization.

    :param t: A Task object containing all the parameters for the image processing.
    :return: A TaskResult object containing information for single file report.
    """
    img = Image.open(t.src_path)
    orig_format = img.format
    orig_mode = img.mode

    folder, filename = os.path.split(t.src_path)
    temp_file_path = os.path.join(folder + "/~temp~" + filename)
    orig_size = os.path.getsize(t.src_path)
    orig_colors, final_colors = 0, 0

    result_format = "JPEG"
    try:
        had_exif = True if piexif.load(t.src_path)['Exif'] else False
    except piexif.InvalidImageDataError:  # Not a supported format
        had_exif = False
    except ValueError:  # No exif info
        had_exif = False

    if t.max_w or t.max_h:
        img, was_downsized = downsize_img(img, t.max_w, t.max_h)
    else:
        was_downsized = False

    if t.grayscale:
        img = make_grayscale(img)

    # only use progressive if file size is bigger
    use_progressive_jpg = orig_size > 10000

    if t.fast_mode:
        quality = t.quality
    else:
        quality, jpgdiff = jpeg_dynamic_quality(img)

    try:
        img.save(temp_file_path,
                 quality=quality,
                 optimize=True,
                 progressive=use_progressive_jpg,
                 format=result_format)
    except IOError:
        ImageFile.MAXBLOCK = img.size[0] * img.size[1]
        img.save(temp_file_path,
                 quality=quality,
                 optimize=True,
                 progressive=use_progressive_jpg,
                 format=result_format)

    if t.keep_exif and had_exif:
        try:
            piexif.transplant(os.path.expanduser(t.src_path), temp_file_path)
            has_exif = True
        except ValueError:
            has_exif = False
    else:
        has_exif = False

    # Only replace the original file if compression did save any space
    final_size = os.path.getsize(temp_file_path)
    if t.no_size_comparison or (orig_size - final_size > 0):
        shutil.move(temp_file_path, os.path.expanduser(t.src_path))
        was_optimized = True
    else:
        final_size = orig_size
        was_optimized = False
        try:
            os.remove(temp_file_path)
        except OSError as e:
            print(f"\nError while removing temporary file.\n{e}\n")

    return TaskResult(t.src_path, orig_format, result_format, orig_mode,
                      img.mode, orig_colors, final_colors, orig_size,
                      final_size, was_optimized, was_downsized, had_exif,
                      has_exif)
except ImportError:
    bEXIFOptionEnabled = False
from PIL import Image, ImageDraw, ImageFont

# Loop through jpg files in current folder
sCurrentPath = os.getcwd()
for file in os.listdir(sCurrentPath):
    if file.endswith(".jpg"):
        sCurrentFileName = os.path.join(sCurrentPath, file)
        print "- File  " + sCurrentFileName
        # get EXIF from file
        if not bEXIFOptionEnabled:
            print "   EXIF not enabled -- Cannot rename file " + sCurrentFileName
        else:
            try:
                exif_dict = piexif.load(sCurrentFileName)
                sNewFileName = exif_dict['0th'][315]
            except:
                sNewFileName = ""
            if sNewFileName == "":
                print "   ERROR   - Cannot rename file   " + sCurrentFileName + "   ... can't retrieve EXIF"
            else:
                sNewFileName = exif_dict['0th'][315]
                # Remove Name and parenthesis
                sNewFileName = sNewFileName[sNewFileName.find("(") + 1:]
                sNewFileName = sNewFileName[:len(sNewFileName) - 1]
                sNewFileName = os.path.join(sCurrentPath, sNewFileName.strip())
                # rename file
                try:
                    os.rename(sCurrentFileName, sNewFileName)
                    print "   SUCCESS - File   " + sCurrentFileName + " --> " + sNewFileName
Beispiel #35
0
if os.path.exists(NEWPATH):
    shutil.rmtree(NEWPATH)
shutil.copytree(PATH, NEWPATH)
logger.info(f'Copy from {PATH} to {NEWPATH}')

# In[9]:

temp = []
for f in os.listdir(NEWPATH):
    if not f.endswith('.jpg'):
        os.remove(os.path.join(NEWPATH, f))
        logger.info(f'Remove {f}')
    else:
        img = Image.open(os.path.join(NEWPATH, f))
        exif_dict = piexif.load(os.path.join(NEWPATH, f))
        if 274 not in exif_dict['0th']:
            logger.info(f'No image metadata: {f}')
        elif exif_dict['0th'][274] == 3:
            exif_dict['0th'][274] = 1
            exif_bytes = piexif.dump(exif_dict)
            PIL.ImageOps.mirror(PIL.ImageOps.flip(img)).save(
                os.path.join(NEWPATH, f), 'jpeg')
            piexif.insert(exif_bytes, os.path.join(NEWPATH, f))
            logger.warning(f'Flipped: {f}')
        elif exif_dict['0th'][274] != 1:
            logger.warning(f'Check orientation: {f}')
logger.info('Done with preprocessing')

# In[ ]:
        #-------------------------------------

    r = results[0]
    myData = [list(r.keys())]

    #make csv template with timestamps
    for i in results:

        srtlong = i['longitude']
        srtlat = i['latitude']
        correctimglist = []

        for j in imagelist:

            file_path = ('images/' + j)
            data = piexif.load(file_path)
            for key in ['Exif', '0th', '1st', 'GPS', 'Interop']:
                key = 'GPS'
                subdata = data[key]
                if (piexif.GPSIFD.GPSLatitude in subdata
                        and piexif.GPSIFD.GPSLongitude in subdata):

                    coords_1 = (_convert_to_degress(
                        subdata[piexif.GPSIFD.GPSLatitude]),
                                _convert_to_degress(
                                    subdata[piexif.GPSIFD.GPSLongitude]))
                    coords_2 = (srtlat, srtlong)

                    distance_in_m = geopy.distance.vincenty(
                        coords_1, coords_2).m
Beispiel #37
0
def optimize_jpeg(
    src: Union[pathlib.Path, io.BytesIO],
    dst: Optional[pathlib.Path] = None,
    quality: Optional[int] = 85,
    fast_mode: Optional[bool] = True,
    keep_exif: Optional[bool] = True,
    **options,
) -> Union[pathlib.Path, io.BytesIO]:
    """method to optimize JPEG files using a pure python external optimizer
    quality: JPEG quality (integer between 1 and 100)
        values: 50 | 55 | 35 | 100 | XX
    keep_exif: Whether to keep EXIF data in JPEG (boolean)
        values: True | False
    fast_mode: Use the supplied quality value. If turned off, optimizer will
               get dynamic quality value to ensure better compression
        values: True | False"""

    ensure_matches(src, "JPEG")

    img = Image.open(src)
    orig_size = (os.path.getsize(src)
                 if isinstance(src, pathlib.Path) else src.getbuffer().nbytes)

    had_exif = False
    if (isinstance(src, io.BytesIO)
            and piexif.load(src.getvalue())["Exif"]) or (isinstance(
                src, pathlib.Path) and piexif.load(str(src))["Exif"]):
        had_exif = True

    # only use progressive if file size is bigger
    use_progressive_jpg = orig_size > 10240  # 10KiB

    if fast_mode:
        quality_setting = quality
    else:
        quality_setting, _ = jpeg_dynamic_quality(img)

    if dst is None:
        dst = io.BytesIO()

    img.save(
        dst,
        quality=quality_setting,
        optimize=True,
        progressive=use_progressive_jpg,
        format="JPEG",
    )

    if isinstance(dst, io.BytesIO):
        dst.seek(0)

    if keep_exif and had_exif:

        piexif.transplant(
            exif_src=str(src.resolve())
            if isinstance(src, pathlib.Path) else src.getvalue(),
            image=str(dst.resolve())
            if isinstance(dst, pathlib.Path) else dst.getvalue(),
            new_file=dst,
        )

    return dst
Beispiel #38
0
#!/usr/bin/python
import os
import re
import piexif
import shutil

exif_dict = piexif.load("/Users/dagmar/Pictures/test/DSCF4890-6.JPG")
for ifd in ("0th", "GPS", "Exif"):
    for tag in exif_dict[ifd]:
        print(piexif.TAGS[ifd][tag]["name"], exif_dict[ifd][tag])

#print (exif_dict["GPS"]["GPSDateStamp"])
Beispiel #39
0
                output_file_name)
            command_list.append(command)
            print("Running: {}".format(command))
            sp.check_output(command, shell=True)
            if USE_MESHROOM_RIG_FOLDER_FORMAT and EXPORT_JPG:

                if "png" in file_name:
                    date_number = int(
                        file_name.replace(".png",
                                          "").replace('converted_', ''))
                else:
                    date_number = int(
                        file_name.replace(".jpg", "").replace('section_', ''))
                print(date_number)

                exif_dict = piexif.load(output_file_name)
                exif_dict['Exif'][piexif.ExifIFD.BodySerialNumber] = bytes(
                    '00{}'.format(rig_index), 'utf-8')
                exif_dict['Exif'][piexif.ExifIFD.FocalLength] = (3, 1)
                exif_dict['0th'][piexif.ImageIFD.Make] = bytes(
                    'GoPro', 'utf-8')
                exif_dict['0th'][piexif.ImageIFD.Model] = bytes(
                    'FUSION', 'utf-8')
                exif_dict['0th'][piexif.ImageIFD.DateTime] = bytes(
                    '2020:01:01 01:00:{:02d}'.format(date_number), 'utf-8')
                exif_bytes = piexif.dump(exif_dict)
                piexif.insert(exif_bytes, output_file_name)

            #print(command)
        if vertical_offset_degree > 0:
            vertical_offset_degree = -vertical_offset_degree
    def set_file_geo_data(file: Path, json):
        """
        Reads the geoData from google and saves it to the EXIF. This works assuming that the geodata looks like -100.12093, 50.213143. Something like that.

        Written by DalenW.
        :param file:
        :param json:
        :return:
        """

        # prevents crashes
        try:
            exif_dict = _piexif.load(str(file))
        except (_piexif.InvalidImageDataError, ValueError):
            exif_dict = {'0th': {}, 'Exif': {}}

        # fetches geo data from the photos editor first.
        longitude = float(json['geoData']['longitude'])
        latitude = float(json['geoData']['latitude'])
        altitude = float(json['geoData']['altitude'])

        # fallbacks to GeoData Exif if it wasn't set in the photos editor.
        # https://github.com/TheLastGimbus/GooglePhotosTakeoutHelper/pull/5#discussion_r531792314
        longitude = float(json['geoData']['longitude'])
        latitude = float(json['geoData']['latitude'])
        altitude = json['geoData']['altitude']
        # Prioritise geoData set from GPhotos editor
        if longitude == 0 and latitude == 0:
            longitude = float(json['geoDataExif']['longitude'])
            latitude = float(json['geoDataExif']['latitude'])
            altitude = json['geoDataExif']['altitude']

        # latitude >= 0: North latitude -> "N"
        # latitude < 0: South latitude -> "S"
        # longitude >= 0: East longitude -> "E"
        # longitude < 0: West longitude -> "W"

        if longitude >= 0:
            longitude_ref = 'E'
        else:
            longitude_ref = 'W'
            longitude = longitude * -1

        if latitude >= 0:
            latitude_ref = 'N'
        else:
            latitude_ref = 'S'
            latitude = latitude * -1

        # referenced from https://gist.github.com/c060604/8a51f8999be12fc2be498e9ca56adc72
        gps_ifd = {_piexif.GPSIFD.GPSVersionID: (2, 0, 0, 0)}

        # skips it if it's empty
        if latitude != 0 or longitude != 0:
            gps_ifd.update({
                _piexif.GPSIFD.GPSLatitudeRef:
                latitude_ref,
                _piexif.GPSIFD.GPSLatitude:
                degToDmsRational(latitude),
                _piexif.GPSIFD.GPSLongitudeRef:
                longitude_ref,
                _piexif.GPSIFD.GPSLongitude:
                degToDmsRational(longitude)
            })

        if not isinstance(altitude, str) and altitude != 0:
            gps_ifd.update({
                _piexif.GPSIFD.GPSAltitudeRef:
                1,
                _piexif.GPSIFD.GPSAltitude:
                change_to_rational(round(altitude))
            })

        gps_exif = {"GPS": gps_ifd}
        exif_dict.update(gps_exif)

        try:
            _piexif.insert(_piexif.dump(exif_dict), str(file))
        except Exception as e:
            print("Couldn't insert geo exif!")
            # local variable 'new_value' referenced before assignment means that one of the GPS values is incorrect
            print(e)
Beispiel #41
0
import easygui
import piexif
print(
    "Select the image files which have JPEG/JPG or TIFF as their extensions, selecting other types will raise errors\n"
)
#for selecting the file
exif_dict = piexif.load(easygui.fileopenbox())
thumbnail = exif_dict.pop("thumbnail")
if thumbnail is not None:
    with open("thumbnail.jpg", "wb+") as f:
        f.write(thumbnail)

#for printing the whole exif_dict
"""        
for ifd_name in exif_dict:
    print("\n{0} IFD:".format(ifd_name))
    for key in exif_dict[ifd_name]:
        try:
            print(key, exif_dict[ifd_name][key][:10])
        except:
            print(key, exif_dict[ifd_name][key])
"""
gps_info = exif_dict['GPS']


#for converting to decimal from degrees minutes seconds
def get_decimal_from_dms(dms, ref):
    degrees = dms[0][0] / dms[0][1]
    minutes = dms[1][0] / dms[1][1] / 60.0
    seconds = dms[2][0] / dms[2][1] / 3600.0
    if ref in ['S', 'W']:
def exif_editor(endereco, titulo):
    exif_dict = piexif.load(endereco)
    exif_dict['0th'][270] = titulo
    exif_bytes = piexif.dump(exif_dict)
    piexif.insert(exif_bytes, endereco)
 def writeToImageExif(self, childName, image):
     user_comment = piexif.helper.UserComment.dump(childName)
     exif_dict = piexif.load(image)
     exif_dict["Exif"][piexif.ExifIFD.UserComment] = user_comment
     exif_bytes = piexif.dump(exif_dict)
     piexif.insert(exif_bytes, image)
Beispiel #44
0
    sys.exit()

file_path = file_root + file_name + '.jpg'

#openedFile = open(file_path)
#readFile = openedFile.read()

#sha1Hash = hashlib.sha1(readFile)
#sha1Hashed = sha1Hash.hexdigest()

img = cv.imread(file_path)
pil_img = Image.open(file_path)

# load exif data
try:
    exif_dict = piexif.load(pil_img.info["exif"])
    exif_dict.pop("thumbnail")
    exif_dict.pop("1st")
except:
    #print('No exif data')
    #sys.exit()

    zeroth_ifd = {}
    exif_ifd = {}
    gps_ifd = {}
    exif_dict = {"0th": zeroth_ifd, "Exif": exif_ifd, "GPS": gps_ifd}

pil_img.close()

# for ifd_name in exif_dict:
#   print("\n{0} IFD:".format(ifd_name))
import piexif, piexif.helper, json, pprint

filename = "photos/cbindonesia_1.jpg"
exif_dict = piexif.load(filename)
user_comment = piexif.helper.UserComment.load(
    exif_dict["Exif"][piexif.ExifIFD.UserComment])
data = json.loads(user_comment)

pprint.pprint(data)
Beispiel #46
0
    def resize_image(self,
                     src,
                     dst,
                     max_size,
                     bigger_panoramas=True,
                     preserve_exif_data=False,
                     exif_whitelist={}):
        """Make a copy of the image in the requested size."""
        if not Image or os.path.splitext(src)[1] in ['.svg', '.svgz']:
            self.resize_svg(src, dst, max_size, bigger_panoramas)
            return
        im = Image.open(src)

        if hasattr(im, 'n_frames') and im.n_frames > 1:
            # Animated gif, leave as-is
            utils.copy_file(src, dst)
            return

        size = w, h = im.size
        if w > max_size or h > max_size:
            size = max_size, max_size

            # Panoramas get larger thumbnails because they look *awful*
            if bigger_panoramas and w > 2 * h:
                size = min(w, max_size * 4), min(w, max_size * 4)

        try:
            exif = piexif.load(im.info["exif"])
        except KeyError:
            exif = None
        # Inside this if, we can manipulate exif as much as
        # we want/need and it will be preserved if required
        if exif is not None:
            # Rotate according to EXIF
            value = exif['0th'].get(piexif.ImageIFD.Orientation, 1)
            if value in (3, 4):
                im = im.transpose(Image.ROTATE_180)
            elif value in (5, 6):
                im = im.transpose(Image.ROTATE_270)
            elif value in (7, 8):
                im = im.transpose(Image.ROTATE_90)
            if value in (2, 4, 5, 7):
                im = im.transpose(Image.FLIP_LEFT_RIGHT)
            exif['0th'][piexif.ImageIFD.Orientation] = 1

        try:
            im.thumbnail(size, Image.ANTIALIAS)
            if exif is not None and preserve_exif_data:
                # Put right size in EXIF data
                w, h = im.size
                if '0th' in exif:
                    exif["0th"][piexif.ImageIFD.ImageWidth] = w
                    exif["0th"][piexif.ImageIFD.ImageLength] = h
                if 'Exif' in exif:
                    exif["Exif"][piexif.ExifIFD.PixelXDimension] = w
                    exif["Exif"][piexif.ExifIFD.PixelYDimension] = h
                # Filter EXIF data as required
                exif = self.filter_exif(exif, exif_whitelist)
                im.save(dst, exif=piexif.dump(exif))
            else:
                im.save(dst)
        except Exception as e:
            self.logger.warn("Can't process {0}, using original "
                             "image! ({1})".format(src, e))
            utils.copy_file(src, dst)
Beispiel #47
0
    def create_image(path):
        try:
            filetype = os.path.splitext(path)[1]

            if filetype == ".mp4" or filetype == ".MP4" or filetype == ".MOV" or filetype == ".mov":
                media_info = MediaInfo.parse(path)
                for track in media_info.tracks:
                    if track.bit_rate is not None and track.track_type == "Video":
                        # get the videos recording date
                        date_time = track.tagged_date
                        year = date_time[4:8]
                        month = date_time[9:11]
                        day = date_time[12:14]
                        hour = date_time[15:17]
                        minute = date_time[18:20]
                        second = date_time[21:23]

                        # if there is no metadata in the video file the tagged_date is UTC 1904-01-01 00:00:00
                        if year == "1904" and use_creation_date == False:
                            print(
                                bcolors.WARNING + "[ WARNING ] " +
                                "Could not retrieve metadata information for: "
                                + bcolors.ENDC + os.path.split(path)[1])

                            if handle_nodate:
                                move_or_copy_nodate(path)

                            return False

                        # FALLBACK
                        elif year == "1904" and use_creation_date:
                            date_time = get_time_from_creation_date(path)
                            year = date_time[0:4]
                            month = date_time[5:7]
                            day = date_time[8:10]
                            hour = date_time[11:13]
                            minute = date_time[14:16]
                            second = date_time[17:19]

            elif filetype == ".jpg" or filetype == ".JPG" or filetype == ".jpeg" or filetype == ".JPEG":
                # get exif information
                exif_dict = piexif.load(path)
                # exif36867 is the creation timestamp
                date_time = bytes.decode(exif_dict["Exif"][36867], "utf-8")
                year = date_time[0:4]
                month = date_time[5:7]
                day = date_time[8:10]
                hour = date_time[11:13]
                minute = date_time[14:16]
                second = date_time[17:19]

            # FALLBACK
            elif use_creation_date:
                date_time = get_time_from_creation_date(path)
                year = date_time[0:4]
                month = date_time[5:7]
                day = date_time[8:10]
                hour = date_time[11:13]
                minute = date_time[14:16]
                second = date_time[17:19]

            else:
                return False

            image = Image(year, month, day, hour, minute, second, path,
                          filetype)

            return image

        except (KeyError, ValueError):
            print(bcolors.WARNING + "[ WARNING ] " +
                  "Could not retrieve exif information for: " + bcolors.ENDC +
                  os.path.split(path)[1])

            # FALLBACK
            if use_creation_date:
                date_time = get_time_from_creation_date(path)
                year = date_time[0:4]
                month = date_time[5:7]
                day = date_time[8:10]
                hour = date_time[11:13]
                minute = date_time[14:16]
                second = date_time[17:19]

                image = Image(year, month, day, hour, minute, second, path,
                              filetype)

                return image

            if handle_nodate:
                move_or_copy_nodate(path)

            return False

        except TypeError:
            print(bcolors.WARNING + "[ WARNING ] " +
                  "Could not retrieve metadata information for: " +
                  bcolors.ENDC + os.path.split(path)[1])

            # FALLBACK
            if use_creation_date:
                date_time = get_time_from_creation_date(path)
                year = date_time[0:4]
                month = date_time[5:7]
                day = date_time[8:10]
                hour = date_time[11:13]
                minute = date_time[14:16]
                second = date_time[17:19]

                image = Image(year, month, day, hour, minute, second, path,
                              filetype)

                return image

            if handle_nodate:
                move_or_copy_nodate(path)

            return False
Beispiel #48
0
def start(pass_index):
    # update the status in daily_passes.json
    with open("/home/pi/website/weather/scripts/daily_passes.json", "r") as f:
        data = json.load(f)
    with open("/home/pi/website/weather/scripts/daily_passes.json", "w") as f:
        data[pass_index]["status"] = "CURRENT"
        json.dump(data, f, indent=4, sort_keys=True)

    # get info about the pass from the daily_passes.json
    with open("/home/pi/website/weather/scripts/daily_passes.json") as f:
        p = json.load(f)[pass_index]

    print(
        "STATUS: {} - ".format(datetime.now().strftime("%Y/%m/%d %H:%M:%S")) +
        "Started processing {}° {} pass at {}".format(
            p['max_elevation'], p['satellite'],
            datetime.fromtimestamp(p['aos']).strftime(
                "%B %-d, %Y at %-H:%M:%S")))

    # assign variables
    with open("/home/pi/website/weather/scripts/secrets.json") as f:
        data = json.load(f)
        lat = data['lat']
        lon = data['lon']
        elev = data['elev']

    sat = p['satellite']
    frequency = p['frequency']
    duration = p['duration']
    max_elevation = p['max_elevation']
    # string used for naming the files  (aos in %Y-%m-%d %H.%M.%S format)
    local_time = datetime.fromtimestamp(p['aos']).strftime("%Y-%m-%d_%H.%M.%S")
    day = str(local_time)[:10]
    # the name of the folder containing all the passes for the day (aos in %Y-%m-%d format)
    outfile = "/home/pi/drive/weather/images/{}/{}/{}".format(
        day, local_time, local_time)
    # the name of the json file containing all the info about the pass
    pass_file = "/home/pi/website/weather/images/{}/{}/{}.json".format(
        day, local_time, local_time)

    try:
        # if this is the first pass of the day, create a new folder for all the images of the day
        if not os.path.exists("/home/pi/drive/weather/images/{}".format(day)):
            os.makedirs("/home/pi/website/weather/images/{}".format(day))
            os.makedirs("/home/pi/drive/weather/images/{}".format(day))

        # create new directory for this pass
        if not os.path.exists("/home/pi/drive/weather/images/{}/{}".format(
                day, local_time)):
            os.makedirs("/home/pi/drive/weather/images/{}/{}".format(
                day, local_time))
            os.makedirs("/home/pi/website/weather/images/{}/{}".format(
                day, local_time))
    except:
        print("Failed creating new directories for the pass. Aborting")
        exit()

    # send console output to log file
    stdout_old = sys.stdout
    log_file = "/home/pi/drive/weather/images/{}/{}/{}.log".format(
        day, local_time, local_time)
    sys.stdout = open(log_file, "a")

    # compute sun elevation
    obs = ephem.Observer()
    obs.lat = str(lat)
    obs.long = str(lon)
    obs.date = datetime.utcfromtimestamp(p['tca'])

    sun = ephem.Sun(obs)
    sun.compute(obs)
    sun_elev = round(float(sun.alt) * 57.2957795,
                     1)  # convert to degrees from radians

    # write sun elevation to pass file
    with open(pass_file, "w") as f:
        pass_info = p
        pass_info["sun_elev"] = sun_elev
        json.dump(pass_info, f, indent=4, sort_keys=True)

    # process depending on the satellite
    if sat[:4] == "NOAA":
        images, main_tag = process_satellite.NOAA(pass_file, outfile, log_file)
    elif sat == "METEOR-M 2":
        images, main_tag = process_satellite.METEOR(pass_file, outfile,
                                                    log_file)

    # upload each image to the internet
    links = {}
    with open(pass_file) as f:
        data = json.load(f)
        for image in images:
            # add metadata to image
            exif_dict = piexif.load(image)
            exif_dict["Exif"][
                piexif.ExifIFD.UserComment] = piexif.helper.UserComment.dump(
                    json.dumps(data), encoding="unicode")
            piexif.insert(piexif.dump(exif_dict), image)

            # upload image and get a link
            tag = image.split(".")[-2]
            link = share.imgbb(image)
            if tag == main_tag:
                main_image = link
            links[tag] = link

    # write pass info to json file
    with open(pass_file) as fr:
        pass_info = json.load(fr)
        with open(pass_file, "w") as fw:
            pass_info['links'] = links
            pass_info["main_image"] = main_image
            json.dump(pass_info, fw, indent=4, sort_keys=True)

    # send discord webhook
    with open("/home/pi/website/weather/scripts/secrets.json") as f:
        data = json.load(f)
        for webhook in data["discord_webhook_urls"]:
            result = share.discord_webhook(pass_file, webhook)
            print(result)

    # update the status in daily_passes.json
    with open("/home/pi/website/weather/scripts/daily_passes.json", "r") as f:
        data = json.load(f)
    with open("/home/pi/website/weather/scripts/daily_passes.json", "w") as f:
        data[pass_index]["status"] = "PASSED"
        json.dump(data, f, indent=4, sort_keys=True)

    # append the pass to the passes list
    with open("/home/pi/website/weather/images/passes.json", "r+") as rf:
        data = json.load(rf)
        with open("/home/pi/website/weather/images/passes.json", "w") as f:
            data.append("/weather/images/{}/{}/{}.json".format(
                day, local_time, local_time))
            json.dump(data, f, indent=4, sort_keys=True)

    # commit changes to git repository
    # print("STATUS {} - ".format(datetime.now().strftime("%Y/%m/%d %H:%M:%S")) +
    #      "Commiting changes to github")
    # os.system(
    #    "/home/pi/website/weather/scripts/commit.sh 'Automatic commit for satellite pass' >> {}"
    #    .format(log_file))

    # set console output back to default
    sys.stdout = stdout_old

    # send status to console
    print(
        "STATUS: {} - ".format(datetime.now().strftime("%Y/%m/%d %H:%M:%S")) +
        "Finished processing {}° {} pass at {}".format(
            p['max_elevation'], p['satellite'],
            datetime.fromtimestamp(p['aos']).strftime(
                "%B %-d, %Y at %-H:%M:%S")))

    # get info about next pass
    next_pass = {}
    for p in json.load(
            open("/home/pi/website/weather/scripts/daily_passes.json")):
        if p["status"] == "INCOMING":
            next_pass = p
            break
    if next_pass == {}:
        print("STATUS: {} - ".format(datetime.now().strftime(
            "%Y/%m/%d %H:%M:%S")) +
              "No more passes to process. Rescheduling...")
    else:
        print("STATUS: {} - ".format(datetime.now().strftime(
            "%Y/%m/%d %H:%M:%S")) +
              "Waiting until {} for {}° {} pass...".format(
                  datetime.fromtimestamp(next_pass['aos']).strftime(
                      "%B %-d, %Y at %-H:%M:%S"), next_pass['max_elevation'],
                  next_pass['satellite']))
from PIL import Image
import piexif
from pprint import pprint
from PIL import ExifTags

im = Image.open("../../_images/rose.jpg")

exif_dict = piexif.load(im.info["exif"])
pprint(exif_dict)
pprint(ExifTags.TAGS)
Beispiel #50
0
 def read(self):
     """ Read EXIF of pictures in media library """
     return piexif.load(self.mediadir_path + self.kwargs["filename"])
    def add_exif_data(self, filename):
        print "----------------------------------------------------------------------------"
        # pop top gps coordinate from queue
        try:
            print "Size of Queue: " + str(
                len(ArduinoUSBconn.connection.gps_queue))
            print ArduinoUSBconn.connection.gps_queue
            location = ArduinoUSBconn.connection.gps_queue.popleft()
        except Exception as e:
            print "Queue is empty"
            print e
            return

        try:
            im = Image.open(FOLDER + "/" + filename)
            exif_dict = piexif.load(im.info["exif"])
            print "AddExif: " + filename
        except Exception as e:
            print "Couldn't open file " + filename
            print "Error: " + e
            print "----------------------------------------------------------------------------"
            return
        """
        image_time_s = exif_dict["Exif"][piexif.ExifIFD.DateTimeOriginal]
        image_time_ms = int(exif_dict["Exif"][piexif.ExifIFD.SubSecTimeOriginal])
        image_time = time.strptime(image_time_s,"%Y:%m:%d %H:%M:%S")
        image_unix = time.mktime(image_time)
        image_unix = image_unix + image_time_ms/int(len(str(image_time_ms)))
        # copy dict for use in case of modification
        gps_dict = ArduinoUSBconn.connection.gps_dict.copy()
        
        
        if self.adds == 0:
            lowest = 10000000000000000000
            for t in gps_dict:
                if t < lowest:
                    lowest = t
            self.beg_obc_clock = lowest
            self.beg_cam_clock = image_unix
            self.adds = 1

        print gps_dict
        print image_unix 
        # offset camera time to obc time
        image_offset = abs(image_unix - self.beg_cam_clock) 

        closest = 0
        smallest = -1
        for k in gps_dict:
            obc_offset = abs(k - self.beg_obc_clock)
            diff = abs(k - image_unix)
            if smallest == -1:
                if diff < 10:
                    closest = k
                    smallest = diff
            else:
                if diff < smallest and diff < 5:
                    closest = k
                    smallest = diff
        if closest not in gps_dict:
            print "ERROR NO GPS TAG FOR THIS IMAGE" + filename
            print "IMAGE TIME = "+str(image_unix)
            print "----------------------------------------------------------------------------"
            return
        print "Image Time: "+ str(image_unix)
        print "Closest GPS Time: "+ str(closest) + " diff: "+str(smallest)
        print "Location: "+ str(gps_dict[closest])
        #location = gps_dict[closest]
        """

        absolute_alt = location["alt"]
        relative_alt = location["rel_alt"]
        calc_ground = abs(absolute_alt - relative_alt)
        lat = location["lat"]
        lon = location["lng"]
        heading = location["heading"]

        # two precision
        absolute_alt = int(round(absolute_alt * 100))
        calc_ground = int(round(calc_ground * 100))
        relative_alt = int(round(relative_alt * 100))

        # three precision
        heading = int(round(heading * 1000))
        lat = int(round(abs(lat * 1000)))
        lon = int(round(abs(lon * 1000)))

        exif_dict["GPS"][piexif.GPSIFD.GPSSpeed] = (calc_ground, 100)
        exif_dict["GPS"][piexif.GPSIFD.GPSAltitude] = (absolute_alt, 100)
        exif_dict["GPS"][piexif.GPSIFD.GPSImgDirection] = (heading, 1000)
        exif_dict["GPS"][piexif.GPSIFD.GPSLongitude] = (lon, 1000)
        exif_dict["GPS"][piexif.GPSIFD.GPSLatitude] = (lat, 1000)
        exif_dict["GPS"][piexif.GPSIFD.GPSTrack] = (relative_alt, 100)
        try:
            exif_bytes = piexif.dump(exif_dict)
            im.save(OUTPUTFOLDER + "/" + filename,
                    "jpeg",
                    exif=exif_bytes,
                    quality=90)
        except Exception as e:
            print "--------"
            print "ERROR Exif data could not be saved"
            print e
            print "Lat " + str(lat)
            print "Long " + str(lon)
            print "Heading " + str(heading)
            print "AAlt " + str(absolute_alt)
            print "RAlt " + str(relative_alt)
            print "CGround " + str(calc_ground)
            print "--------"
        print "exif data added"
        print "----------------------------------------------------------------------------"
Beispiel #52
0
def rotate_image(image_data, method=None, REQUEST=None):
    """Rotate Image if it has Exif Orientation Informations other than 1.

    Do not use PIL.Image.rotate function as this did not transpose the image,
    rotate keeps the image width and height and rotates the image around a
    central point. PIL.Image.transpose also changes Image Orientation.
    """
    orientation = 1  # if not set assume correct orrinetation --> 1
    data = _ensure_data(image_data)
    img = PIL.Image.open(StringIO(data))

    exif_data = None
    if 'exif' in img.info:
        try:
            exif_data = piexif.load(img.info['exif'])
        except ValueError:
            log.warn('Exif information currupt')
            pass
        if exif_data and piexif.ImageIFD.Orientation in exif_data['0th']:
            orientation = exif_data['0th'][piexif.ImageIFD.Orientation]
        if exif_data and \
                (not exif_data['0th'].get(piexif.ImageIFD.XResolution) or
                 not exif_data['0th'].get(piexif.ImageIFD.YResolution)):
            exif_data['0th'][piexif.ImageIFD.XResolution] = (img.width, 1)
            exif_data['0th'][piexif.ImageIFD.YResolution] = (img.height, 1)
    if exif_data is None:
        width, height = img.size
        exif_data = {
            '0th': {
                piexif.ImageIFD.XResolution: (width, 1),
                piexif.ImageIFD.YResolution: (height, 1),
            }
        }

    if method is not None:
        orientation = method

    log.debug('Rotate image with input orientation: %s', orientation)

    fmt = img.format
    if orientation == 1:  # not transform necessary
        # img = img
        pass
    elif orientation == 2:
        img = img.transpose(PIL.Image.FLIP_LEFT_RIGHT)
    elif orientation == 3:
        img = img.transpose(PIL.Image.ROTATE_180)
    elif orientation == 4:
        img = img.transpose(PIL.Image.ROTATE_180).transpose(
            PIL.Image.FLIP_LEFT_RIGHT)
    elif orientation == 5:
        img = img.transpose(PIL.Image.ROTATE_270).transpose(
            PIL.Image.FLIP_LEFT_RIGHT)
    elif orientation == 6:
        img = img.transpose(PIL.Image.ROTATE_270)
    elif orientation == 7:
        img = img.transpose(PIL.Image.ROTATE_90).transpose(
            PIL.Image.FLIP_LEFT_RIGHT)
    elif orientation == 8:
        img = img.transpose(PIL.Image.ROTATE_90)

    if orientation in [5, 6, 7, 8]:
        if exif_data['0th'][piexif.ImageIFD.XResolution] and \
                exif_data['0th'][piexif.ImageIFD.YResolution]:
            exif_data['0th'][piexif.ImageIFD.XResolution], \
                exif_data['0th'][piexif.ImageIFD.YResolution] = \
                exif_data['0th'][piexif.ImageIFD.YResolution], \
                exif_data['0th'][piexif.ImageIFD.XResolution]
        else:
            exif_data['0th'][piexif.ImageIFD.XResolution], \
                exif_data['0th'][piexif.ImageIFD.YResolution] = \
                (img.width, 1), (img.height, 1)

    # set orientation to normal
    exif_data['0th'][piexif.ImageIFD.Orientation] = 1

    try:
        exif_bytes = piexif.dump(exif_data)
    except Exception as e:
        log.warn(e)
        del (exif_data['Exif'][piexif.ExifIFD.SceneType])
        # This Element piexif.ExifIFD.SceneType cause error on dump
        exif_bytes = piexif.dump(exif_data)
    output_image_data = StringIO()
    img.save(output_image_data, format=fmt, exif=exif_bytes)
    width, height = img.size
    return output_image_data.getvalue(), width, height, exif_data
        str(image_location))
    extensions = ("*.jpg", "*.JPG", "*.JPEG", "*.jpeg")
    folder_contents = []
    for extension in extensions:
        folder_contents.extend(glob.glob(image_location + "/**/" + extension))

    if len(folder_contents) > 0:
        print(
            str(datetime.now()) + " [INFO] Found " +
            str(len(folder_contents)) + " Images to process")

        for image_location in folder_contents:

            if os.path.isfile(image_location):

                exif_dict = piexif.load(image_location)

                for ifd in ("0th", "Exif", "GPS", "1st"):
                    for tag in exif_dict[ifd]:

                        if piexif.TAGS[ifd][tag]["name"] == "DateTime":
                            date_of_image["DateTime"] = exif_dict[ifd][
                                tag].decode("utf-8")

                        if piexif.TAGS[ifd][tag]["name"] == "DateTimeOriginal":
                            date_of_image["DateTimeOriginal"] = exif_dict[ifd][
                                tag].decode("utf-8")

                if "DateTimeOriginal" in date_of_image:
                    img_date = datetime.strptime(
                        date_of_image["DateTimeOriginal"], "%Y:%m:%d %H:%M:%S")
 def __init__(self, file_dir, floatview_info, raw_info):
     self.file_dir = file_dir
     self.floatview_info = floatview_info
     self.raw_info = raw_info
     self.exif_dict = piexif.load(self.file_dir)
     self.is_dirty = False
Beispiel #55
0
print('读取 image')
if not os.path.exists('image'):
    print('image 文件夹不存在')
    exit(0)

print('清理dist')
if os.path.exists('dist'):
    shutil.rmtree('dist')
os.mkdir('dist')

props = readprops('reformat.props')

tSize = (160, 120)
finalSize = (960, 1280)
exif = piexif.load(open('exif.bin', 'rb').read())
# 根据props修改信息
exif['0th'][305] = struct.pack('%ds' % (len(props['productVersion'])),
                               bytes(props['productVersion'], 'utf-8'))
exif['0th'][306] = struct.pack(
    '19s', bytes(props['time_str'].replace('-', ':'), 'utf-8'))
exif['Exif'][36867] = struct.pack(
    '19s', bytes(props['time_str'].replace('-', ':'), 'utf-8'))
exif['Exif'][36868] = struct.pack(
    '19s', bytes(props['time_str'].replace('-', ':'), 'utf-8'))
pt = props['productType'] + ' front camera 2.15mm f/2.4'
exif['Exif'][42036] = struct.pack('%ds' % (len(pt)), bytes(pt, 'utf-8'))


def handleDir(sub):
    currDir = os.path.join('image', sub)
Beispiel #56
0
 def load_exif(self):
     print("LOAD EXIF")
     try:
         self.exif_dict = piexif.load(self.file_path)
     except Exception as e:
         print(e)
Beispiel #57
0
# from https://piexif.readthedocs.io/en/latest/functions.html#load

import pickle
import piexif

exifDict = piexif.load("image_mod.jpg")

for ifdName in exifDict:
    print("\n{0} IFD:".format(ifdName))
    if isinstance(exifDict[ifdName], dict):
        for key in exifDict[ifdName]:
            try:
                data = exifDict[ifdName][key]
                if isinstance(data, bytes):
                    if key == piexif.ExifIFD.MakerNote:
                        d = pickle.loads(data)
                        print(key, d)
                    elif key == piexif.ExifIFD.UserComment:
                        if data[0:8] == b"UNICODE\0":
                            print(key, data[8:].decode("utf-8"))
                        else:
                            print(f"{key} type {type(data)}: {data[:10]}")
                else:
                    print(key, exifDict[ifdName][key][:10])
            except:
                print(key, exifDict[ifdName][key])
    else:
        print(f"{ifdName} is type {type(exifDict[ifdName])}")
    def batch(self, should_rename=True, should_add_exif=True):
        # re constants
        p_date = re.compile(
            r"(\d{4})(0[1-9]|1[0-2])(0[1-9]|[1-2]\d|3[0-1])[ _]([0-1]\d|2[0-3])([0-5]\d)([0-5]\d)"
        )
        p_floatview_json = re.compile(r"^floatview_photo_\d{5}-\d{5}.json$")
        p_raw_json = re.compile(r"^photo_\d{5}-\d{5}.json$")

        target_dir = os.path.join(os.getcwd(), self.target_uin, "photo")
        if not os.path.exists(target_dir):
            print("路径不存在,请确认照片已下载,并在本文件尾部添加目标QQ号")

        # form album list
        album_info_dir = os.path.join(target_dir, "album_info.json")
        with open(album_info_dir, "r", encoding="utf-8") as album_info_f:
            album_info = json.load(album_info_f)
        album_list = get_album_list_data(album_info['data'])

        # No album at all!
        if len(album_list) <= 0:
            print("【json记录中无相册!】")
            return

        # do for every album
        for album in album_list:
            album_dir = ""
            files_in_target_dir = os.listdir(target_dir)
            album_id_purged = purge_file_name(album["id"])

            # find album folder
            for file_name_in_target_dir in files_in_target_dir:
                if album_id_purged in file_name_in_target_dir:
                    album_dir = os.path.join(target_dir,
                                             file_name_in_target_dir)

                    # rename album folder
                    if should_rename:
                        if not re.search(p_date, file_name_in_target_dir):
                            album_create_timestamp = int(
                                album["createtime"])  # 取相册创建时间
                            album_create_date = time.strftime(
                                '%Y%m%d %H%M%S',
                                time.localtime(album_create_timestamp))
                            file_name_in_target_dir_new = album_create_date + " " + file_name_in_target_dir
                            album_dir_new = os.path.join(
                                target_dir, file_name_in_target_dir_new)
                            os.rename(album_dir, album_dir_new)
                            album_dir = album_dir_new

                    break
            if album_dir == "":
                print("相册文件夹缺失:", os.path.join(target_dir, album["name"]))
                continue

            # find floatview and raw json (500+ json文件会分裂。。)
            files_in_album_dir = os.listdir(album_dir)
            floatview_json_dir_list = []
            raw_json_dir_list = []
            for file_name_in_album_dir in files_in_album_dir:
                if re.search(p_floatview_json, file_name_in_album_dir):
                    floatview_json_dir_list.append(
                        os.path.join(album_dir, file_name_in_album_dir))
                elif re.search(p_raw_json, file_name_in_album_dir):
                    raw_json_dir_list.append(
                        os.path.join(album_dir, file_name_in_album_dir))

            # floatview or raw json is missing!
            if len(floatview_json_dir_list) == 0 or len(
                    raw_json_dir_list) == 0:
                print("【相册中照片json数据缺失】:", album_dir)
                continue

            floatview_list = []
            raw_list = []
            for floatview_json_dir in floatview_json_dir_list:
                with open(floatview_json_dir, "r",
                          encoding="utf-8") as floatview_json_f:
                    floatview_json = json.load(floatview_json_f)
                    for _floatview_info in floatview_json["data"]["photos"]:
                        floatview_list.append(_floatview_info)
            for raw_json_dir in raw_json_dir_list:
                with open(raw_json_dir, "r", encoding="utf-8") as raw_json_f:
                    raw_json = json.load(raw_json_f)
                    for _raw_info in raw_json["data"]["photoList"]:
                        raw_list.append(_raw_info)

            # find downloaded folder and file list within
            downloaded_dir = os.path.join(album_dir, "downloaded")
            # downloaded folder is missing!
            if not os.path.exists(downloaded_dir):
                print("【无downloaded文件夹】:", downloaded_dir)
                continue
            photos_in_album_downloaded_dir = os.listdir(downloaded_dir)

            # start to handle every photo within an album

            # floatview_info
            for floatview_info in floatview_list:
                lloc = floatview_info["lloc"]

                # find raw_info
                raw_info = None
                for _raw_info in raw_list:
                    if _raw_info["lloc"] == lloc:
                        raw_info = _raw_info
                        break

                # find photo_dir
                photo_dir = ""
                lloc_purged = purge_file_name(lloc)
                for photo_name in photos_in_album_downloaded_dir:
                    if lloc_purged in photo_name:
                        photo_dir = os.path.join(downloaded_dir, photo_name)
                        break

                if photo_dir == "":
                    print("照片缺失:", os.path.join(downloaded_dir, lloc_purged))
                    continue

                # recover EXIF
                if should_add_exif:
                    try:
                        photoExifRecover = PhotoExifRecover(
                            photo_dir, floatview_info, raw_info)
                        photoExifRecover.recover()
                    except Exception as e:
                        error_message = "EXIF写入失败:" + photo_dir + "\n↘失败原因:" + str(
                            e)
                        print(error_message)
                        self.e.append(error_message)
                        continue  # 对于EXIF写入发生异常的文件跳过重命名步骤

                # rename photo
                if should_rename:
                    [dir_name, photo_name] = os.path.split(photo_dir)
                    if not re.search(p_date, photo_name):
                        exif_in_file = piexif.load(photo_dir)
                        if "Exif" in exif_in_file.keys() \
                                and piexif.ExifIFD.DateTimeOriginal in exif_in_file["Exif"].keys() \
                                and exif_in_file["Exif"][piexif.ExifIFD.DateTimeOriginal]:
                            photo_create_date = \
                                bytes.decode(exif_in_file["Exif"][piexif.ExifIFD.DateTimeOriginal]).replace(":", "")
                            photo_name_new = photo_create_date + " " + photo_name
                            photo_dir_new = os.path.join(
                                dir_name, photo_name_new)
                            os.rename(photo_dir, photo_dir_new)
                            photoExifRecover.file_dir = photo_dir_new
                            photo_dir = photo_dir_new
Beispiel #59
0
 def __init__(self, filename):
     self.filename = filename
     self.img = Image.open(filename)
     self.exif = piexif.load(filename)
     self._datetime_original = ''
Beispiel #60
-1
    def write_gps(filename, lat, longit, altitude): #lat and long are decimals
        gps = {} #create array

        #Altitude
        if altitude<0:
            gps[piexif.GPSIFD.GPSAltitudeRef] = 1; #Below see level
        else:
            gps[piexif.GPSIFD.GPSAltitudeRef] = 0; #Above see level
            gps[piexif.GPSIFD.GPSAltitude]= (int(abs(altitude)*100),100)
  
        #Latitude
        if lat<0:
            gps[piexif.GPSIFD.GPSLatitudeRef] = "S"
        else:
            gps[piexif.GPSIFD.GPSLatitudeRef] = "N"
   
        latd,latm,lats = ExifWriter._decdeg2dms(lat)
        gps[piexif.GPSIFD.GPSLatitude] = [(latd,1),(latm,1),(lats*100,100)];
  
        #Longitude
        if longit<0:
            gps[piexif.GPSIFD.GPSLongitudeRef] = "W"
        else:
            gps[piexif.GPSIFD.GPSLongitudeRef] = "E"
  
        longd,longm,longs = ExifWriter._decdeg2dms(longit)
        gps[piexif.GPSIFD.GPSLongitude] = [(longd,1),(longm,1),(longs*100,100)];

        exifdict =  piexif.load(filename)
        exifdict["GPS"] = gps

        exif_bytes = piexif.dump(exifdict)
        piexif.insert(exif_bytes, filename)
        exifdict = piexif.load(filename)