from exif import Image print("PROGRAMMED BY : 01011000 for SpyHackerZ Members") ipath = input("IMAGE NAME in 'THIS FOLDER' : ") with open(ipath, "rb") as imagefile: i = Image(imagefile) tarih = i.datetime aci = i.gps_img_direction kordinat = i.gps_latitude, " N - ", i.gps_longitude, "E " yazilim = i.software model = i.model distance = i.subject_distance print("DATE : ", tarih, "\n", 'COMPASS :'******'METRIC' :", distance)
class TestReadExif(unittest.TestCase): """Test cases for reading EXIF attributes.""" def setUp(self): """Open sample image file in binary mode for use in test cases.""" grand_canyon = os.path.join(os.path.dirname(__file__), 'grand_canyon.jpg') with open(grand_canyon, 'rb') as image_file: self.image = Image(image_file) assert self.image.has_exif def test_get_method(self): """Test behavior when accessing tags using the ``get()`` method.""" self.assertIsNone(self.image.get('fake_attribute')) self.assertEqual(self.image.get('light_source', default=-1), -1) # tag not in image self.assertEqual(self.image.get('make'), Baseline("""Apple""")) def test_handle_bad_attribute(self): """Verify that accessing a nonexistent attribute raises an AttributeError.""" with self.assertRaisesRegex(AttributeError, "unknown image attribute fake_attribute"): self.image.fake_attribute def test_handle_unset_attribute(self): """Verify that accessing an attribute not present in an image raises an AttributeError.""" with self.assertRaisesRegex( AttributeError, "image does not have attribute light_source"): self.image.light_source def test_index_accessor(self): """Test accessing attributes using index syntax.""" self.assertEqual(self.image["datetime"], Baseline("""2018:03:12 10:12:07""")) def test_read_ascii(self): """Test reading ASCII tags and compare to known baseline values.""" self.assertEqual(self.image.datetime, Baseline("""2018:03:12 10:12:07""")) self.assertEqual(self.image.make, Baseline("""Apple""")) self.assertEqual(self.image.model, Baseline("""iPhone 7""")) self.assertEqual(self.image.gps_latitude_ref, Baseline("""N""")) self.assertEqual(self.image.gps_longitude_ref, Baseline("""W""")) def test_read_byte(self): """Test reading BYTE tags and compare to known baseline values.""" self.assertEqual(str(self.image.gps_altitude_ref), Baseline("""0""")) def test_read_long(self): """Test reading LONG tags and compare to known baseline values.""" self.assertEqual(str(self.image.jpeg_interchange_format), Baseline("""6410""")) self.assertEqual(str(self.image.jpeg_interchange_format_length), Baseline("""4507""")) def test_read_rational(self): """Test reading RATIONAL tags and compare to known baseline values.""" self.assertEqual( str(self.image.gps_altitude)[:13], Baseline("""2189.98969072""")) self.assertEqual(str(self.image.gps_latitude), Baseline("""(36.0, 3.0, 11.08)""")) self.assertEqual(str(self.image.gps_longitude), Baseline("""(112.0, 5.0, 4.18)""")) self.assertEqual(str(self.image.x_resolution), Baseline("""72.0""")) self.assertEqual(str(self.image.y_resolution), Baseline("""72.0""")) def test_read_short(self): """Test reading a SHORT tag and compare to a known baseline value.""" self.assertEqual(str(self.image.metering_mode), Baseline("""5""")) def test_read_srational(self): """Test reading a SRATIONAL tag and compare to a known baseline value.""" self.assertEqual( str(self.image.brightness_value)[:13], Baseline("""11.3644957983"""))
def process_one_file( in_file: Path, out_file: Path, strategies: List[str], formats: List[str] ): if not in_file.is_file(): return if in_file.name.startswith("."): return if in_file.suffix == ".json": return print(f"{esc(1)}{esc(96)}{in_file.name}{esc(0)} =>\t", end="") date: Optional[datetime] = None location: Optional[CoordinatesDMS] = None image: Optional[Image] = None for strategy in reversed(strategies): strategy = strategy.lower() if strategy == "exif": try: with in_file.open("rb") as fo: image = Image(fo) except Exception: image = None continue e_date, e_location = get_info_from_exif(image) date = e_date or date location = e_location or location elif strategy == "json": j_date, j_location = get_info_from_json(in_file) date = j_date or date location = j_location or location elif strategy == "filename": f_date, f_location = get_info_from_filename(in_file, formats) date = f_date or date location = f_location or location if date is None: print(f"{esc(91)}no date{esc(0)}, ", end="") else: print(f"{esc(92)}{date.isoformat()}{esc(0)}, ", end="") if image is not None: image.datetime = date.strftime(DATETIME_STR_FORMAT) if location is None: print(f"{esc(91)}no location{esc(0)}") else: print(f"{esc(92)}{coords_dms2dec(location)}{esc(0)}") if image is not None: try: ( (image.gps_latitude, image.gps_latitude_ref), (image.gps_longitude, image.gps_longitude_ref), ) = location except TypeError: pass if image is not None: out_file.write_bytes(image.get_file()) else: out_file.write_bytes(in_file.read_bytes()) if date is not None: os.utime(out_file, (date.timestamp(), date.timestamp()))
from exif import Image import sys if len(sys.argv) != 3: print("usage: python3 findexp.py [src_dir] [img_list]") print("e.g: python3 findexp.py ./myimg/ myimg_list.txt") exit() d = sys.argv[1] if d[-1] != '/': d = d + '/' for i in open(sys.argv[2], 'r'): with open(d + i[:-1], 'rb') as image_file: img = Image(image_file) print(i[:-1], img.exposure_time)
from GetSpatialData import openGpxFiles import coordFunction from datetime import * from tkinter import filedialog timeshift = -0.75 tableLonLatAlt = openGpxFiles.openGpxFiles() LatLonAltInterpolFunc = coordFunction.CoordFunction(tableLonLatAlt) photoFileNames = filedialog.askopenfilenames() for photoFileName in photoFileNames: file = open(photoFileName, 'rb') image = Image(file) file.close() print(dir(image)) print(image.gps_longitude_ref) print(image.gps_longitude) print(image.gps_altitude) print(image.gps_altitude_ref) picDateTime = image.datetime + timedelta(seconds=timeshift) photoUnixTimestamp = datetime.strptime(picDateTime, '%Y:%m:%d %H:%M:%S').timestamp() print(image.datetime) print(image.datetime_digitized) print(picDateTime) print(photoUnixTimestamp) latLonAlt = LatLonAltInterpolFunc.getLatLonAlt(photoUnixTimestamp) degLat = int(latLonAlt[0]) minLat = int((latLonAlt[0] - degLat) * 60)
def get_images(): response = [] image_names = os.listdir('static/images') for image_name in image_names: with open(f"static/images/{image_name}", "rb") as image_file: image = Image(image_file) for val in dir(image): print(val) response.append({ 'path': f'static/images/{image_name}', 'model': image.get('model', None) if image.has_exif else None, 'lens': image.get('lens_model', None) if image.has_exif else None, 'taken': image.get('datetime_original', None) if image.has_exif else None, 'focalLength': image.get('focal_length', None) if image.has_exif else None, 'exposureMode': image.get('exposure_mode', None) if image.has_exif else None, 'apertureValue': image.get('aperture_value', None) if image.has_exif else None, 'shutterSpeedValue': image.get('shutter_speed_value', None) if image.has_exif else None, 'sceneCaptureType': image.get('scene_capture_type', None) if image.has_exif else None, 'software': image.get('software', None) if image.has_exif else None, 'colorSpace': image.get('color_space', None) if image.has_exif else None, }) return app.response_class(mimetype='application/json', response=json.dumps(response))
def main(search: pathlib.Path, target: pathlib.Path, recursive=True, print_progress=False, date_dirs=False, move=False, verbose=False): search_string = None if recursive: search_string = '**/*.JPG' else: search_string = '*.JPG' dates = {} images = list(search.glob(search_string)) n_images = len(images) steps = [int(x * (n_images / 10)) for x in range(10)] for i, image in enumerate(images): if i in steps and print_progress: print(f'{((i / n_images) * 100)}%') try: if verbose: print(str(image.resolve())) with image.resolve().open('rb') as f: exif_image = Image(f) date, time = exif_image.datetime_original.split(' ') year, month, day = map(int, date.split(':')) hour, minute, second = map(int, time.split(':')) dt = datetime.datetime(year=int(year), month=int(month), day=int(day), hour=int(hour), minute=int(minute), second=int(second)) if dt not in dates: dates[dt] = list() dates[dt].append(image.resolve()) except KeyError: print(f'No exif: {image.resolve()}') print('Start copying') for date, file_list in dates.items(): for i, path in enumerate(file_list): file_name = (f'{date.year:02}{date.month:02}{date.day:02}', f'{date.hour:02}{date.minute:02}{date.second:02}', f'{i+1:02}.JPG') file_name = '_'.join(file_name) new_path = target if date_dirs: new_path = new_path / \ f'{date.year:04}' / \ f'{date.month:02}' / \ f'{date.day:02}' if not new_path.exists(): new_path.mkdir(parents=True) new_path = new_path / file_name if verbose: print(f'Copy {path} -> {new_path}') if move: path.rename(new_path) else: shutil.copyfile(path, new_path)
while new_bear < 0: new_bear += 360 while new_bear > 360: new_bear -= 360 lonref, lon2 = to_gps_latlon(new_lon, ('E', 'W')) latref, lat2 = to_gps_latlon(new_lat, ('N', 'S')) if args.mask: image = cv2.bitwise_and(image, image, mask=mask) if args.crop_top + args.crop_bottom + args.crop_left + args.crop_right > 0: height, width, channels = image.shape image = image[args.crop_top:height - args.crop_bottom, args.crop_left:width - args.crop_right] cv2.imwrite("tmp.jpg", image) e_image = Image("tmp.jpg") e_image.gps_latitude = lat2 e_image.gps_latitude_ref = latref e_image.gps_longitude = lon2 e_image.gps_longitude_ref = lonref e_image.gps_img_direction = new_bear e_image.gps_dest_bearing = new_bear e_image.make = make e_image.model = model datetime_taken = datetime.fromtimestamp(new_ts + args.timezone * 3600) e_image.datetime_original = datetime_taken.strftime( DATETIME_STR_FORMAT) with open(
import datetime import os from typing import List, TypedDict import gpxpy import gpxpy.gpx import pytz from exif import Image from GPSPhoto import gpsphoto base_directory = os.path.expanduser("~") + "/Pictures/" current_image_path = base_directory + "DSC00572.jpg" with open(current_image_path, "rb") as image_file: exif_image = Image(image_file) image_datetime = datetime.datetime.strptime( exif_image.datetime_original + " " + exif_image.offset_time, "%Y:%m:%d %H:%M:%S %z", ) # Is this right? I hate timezones, I'm pretty sure datetime comparison works anyway # without making this UTC, but I don't care to look it up right now. image_time_utc = (image_datetime - image_datetime.utcoffset()).replace(tzinfo=pytz.UTC) gps_photo = gpsphoto.GPSPhoto(current_image_path) gpx_file = open(base_directory + "bon-tempe-lake-lagunitas.gpx", "r") gpx = gpxpy.parse(gpx_file) class Point(TypedDict):
def get_exif(image, row): with open(image['file'], 'rb') as image_file: my_image = ExifImage(image_file) if my_image.has_exif: for tag in EXIF_TAGS: row[tag] = my_image.get(tag)
# >>> Telegram Chanell : https://t.me/MONSTER_SECURIT <<< # >>> Web Sayte : www.Monster-Security.blogfa.com <<< # </> MONSTER_hp </> from os import popen from exif import Image print(" ____ _ _ __ __ _ _") print("| _ \| |__ ___ | |_ ___ | \/ | ___ __| | ___| |") print("| |_) | '_ \ / _ \| __/ _ \ _____| |\/| |/ _ \ / _` |/ _ \ |") print("| __/| | | | (_) | || (_) |_____| | | | (_) | (_| | __/ |") print("|_| |_| |_|\___/ \__\___/ |_| |_|\___/ \__,_|\___|_|") print('') print(" >>> GitHub : https://github.com/MONSTER-hp/MONSTER_HACK <<<") print('') print(" >>> Telegram Chanell : https://T.me/MONSTER_SECURIT <<<") print('') print(" >>> Web Sayte : www.Monster-Security.blogfa.com <<<") print('') print('') pic = input("Photo Address : ") img = Image(open(pic, "rb")) try: model = img.model except: exit() print("Model : {}".format(model)) command = "google https://www.google.com/search?q=\"{}\"".format(model) popen(command) #HACKER BY MONSTER_HP
def exif_directory(img_path): with open(img_path, 'rb') as fo: my_img = Image(fo) return dir(my_img)
image_name = "080726 1020.jpg" image_file_path = os.path.join(BASE_DIR, "teszt_kepek/kepek_1", image_name) # image_hash = hashlib.sha3_512(open(image_file_path, 'rb').read()).hexdigest() # print(image_hash, image_hash.digest_size, image_hash.block_size) #print(hashlib.algorithms_available) image_hash = hashlib.blake2b(open(image_file_path, 'rb').read()).hexdigest() print(image_hash) print(image_file_path) # sys.exit() with open(image_file_path, 'rb') as image_file: my_image = Image(image_file) image_date = my_image.get('datetime_original', None) if image_date: image_date_part_1 = image_date.split()[0].replace(":", "-") print(image_date_part_1[:7]) target_dir = os.path.join(BASE_DIR, image_date_part_1[:7]) if not os.path.exists(target_dir): os.mkdir(target_dir) else: for root, dirs, files in os.walk(target_dir, topdown=True): for file in files: print(file) name, ext = os.path.splitext(file) print(name, ext)
transformation_funcs = { 1: lambda img: img.rotate(180, resample=Image.BICUBIC, expand=True), # used only if rotate-only-orientation-1-by-180 is True 6: lambda img: img.rotate(-90, resample=Image.BICUBIC, expand=True), 8: lambda img: img.rotate(90, resample=Image.BICUBIC, expand=True), 3: lambda img: img.rotate(180, resample=Image.BICUBIC, expand=True), 2: lambda img: img.transpose(Image.FLIP_LEFT_RIGHT), 5: lambda img: img.rotate(-90, resample=Image.BICUBIC, expand=True).transpose(Image.FLIP_LEFT_RIGHT), 7: lambda img: img.rotate(90, resample=Image.BICUBIC, expand=True).transpose(Image.FLIP_LEFT_RIGHT), 4: lambda img: img.rotate(180, resample=Image.BICUBIC, expand=True).transpose(Image.FLIP_LEFT_RIGHT), } for img_path in glob(os.path.join(args.dir, '*.jpg')): print(img_path) with open(img_path, 'rb') as image_file: my_image = ExifImage(image_file) try: orientation = my_image.orientation.value except: print(' N/A skipping') continue if orientation == 1: if not args.rotate_only_orientation_1_by_180: print(' 1 skipping') continue else: print(' ', orientation, 'transforming (180° rotation)') else: if not args.rotate_only_orientation_1_by_180: print(' ', orientation, 'transforming') else:
"-n", default="locations.shp", required=False, help="Name to assign to the file.") args = parser.parse_args() imgs_path = args.imgs_folder if imgs_path[-1] != '/': imgs_path += '/' imgs_list = glob.glob(imgs_path + '*.jpg') points = [] for img_name in imgs_list: with open(img_name, 'rb') as img: img = Image(img) lon = img.gps_longitude lat = img.gps_latitude location = "{} {}m {}s N {} {}m {}s E".format(lat[0], lat[1], lat[2], lon[0], lon[1], lon[2]) point = Point(location) point = shg.Point(point.longitude, point.latitude) points.append(point) # write the points to a shapefile gsr = gpd.GeoSeries(points) gsr.crs = {'init': 'epsg:4326'} gsr = gsr.to_crs({'init': 'epsg:3857'}) output_folder = args.output_folder filename = args.filename
if coords_ref == "S" or coords_ref == "W": decimal_degrees = -decimal_degrees return decimal_degrees def create_dir(dir_name): if not os.path.isdir(dir_name): os.mkdir(dir_name) print(f'Creating {dir_name} folder') for i in range(len(images)): with open(os.path.join(image_dir_path, images[i]), "rb") as img_file: img = Image(img_file) if img.has_exif: if hasattr(img, 'datetime_original'): year = img.datetime_original.split(" ")[0].split(":")[0] month = img.datetime_original.split(" ")[0].split(":")[1] else: print( f'Image {i+1} has no datetime information, skipping image.' ) continue if hasattr(img, 'gps_latitude'): decimal_lat = dms_coords_to_dd_coords(img.gps_latitude, img.gps_latitude_ref)
def main(argv=None): '''Command line options.''' program_name = os.path.basename(sys.argv[0]) if argv is None: argv = sys.argv[1:] try: # setup option parser #parser = argparse.OptionParser(version=program_version_string, epilog=program_longdesc, description=program_license) parser = argparse.ArgumentParser() parser.add_argument("infile", help="set input folder", metavar="INPUTFOLDER") parser.add_argument( "apikey", help= "apikey for bing maps, see https://docs.microsoft.com/en-us/bingmaps/getting-started/bing-maps-dev-center-help/getting-a-bing-maps-key", metavar="APIKEY") parser.add_argument("-v", "--verbose", dest="verbose", action="count", help="set verbosity level", default=0) parser.add_argument("-o", "--out", dest="outfile", help="set output path", metavar="FILE", default='result.jpg') parser.add_argument("-n", "--numcols", dest="numcols", help="number of columns", type=int, default=4) parser.add_argument("-s", "--size", dest="size", help="size, default 256", type=int, default=256) parser.add_argument("-d", "--dimension", dest="dimension", help="amount of columns the map uses", type=int, default=2) parser.add_argument( "-z", "--zoom", dest="zoom", help="zoom of map (0-22), more = more zoomed, 0 = best fit", type=int, default=0) parser.add_argument("-b", "--begin", dest="begin", help="first character of label", type=int, default=5) parser.add_argument("-a", "--amount", dest="amount", help="amount of characters for label", choices=[1, 2, 3], type=int, default=3) #requiredNamed.add_argument("-k", "--key", dest="apikey", help="apikey for bing maps, see https://docs.microsoft.com/en-us/bingmaps/getting-started/bing-maps-dev-center-help/getting-a-bing-maps-key") # set defaults #parser.set_defaults(outfile="./out.txt", infile="./in.txt") # process options (args) = parser.parse_args(argv) #args.apikey= args.key; if args.size > 512 or args.size < 64: parser.error('size invalid (64-512)') if args.verbose > 0: print("verbosity level = %d" % args.verbose) if args.infile: print("folder = %s" % args.infile) if args.outfile: print("outfile = %s" % args.outfile) # MAIN BODY # from exif import Image pos = [] for file in os.listdir(args.infile): if (file.lower().endswith(".jpg")): if args.verbose > 0: print(os.path.join(args.infile, file)) with open(os.path.join(args.infile, file), 'rb') as image_file: my_image = Image(image_file) #print(dir(my_image)); #print(my_image.orientation); try: #print('x'+str(my_image.gps_latitude)); #print('y'+str(my_image.gps_longitude)); try: pos.append( (file, my_image.gps_longitude, my_image.gps_latitude, os.path.join(args.infile, file), my_image.orientation)) except: pos.append((file, my_image.gps_longitude, my_image.gps_latitude, os.path.join(args.infile, file), 1)) except AttributeError as a: if args.verbose > 0: print( '\tWARNING: ignored - no geopos or orientation found' ) pass mapsize = (args.size * args.dimension) url = "https://dev.virtualearth.net/REST/v1/Imagery/Map/AerialWithLabels?mapSize=" + str( mapsize) + "," + str(mapsize) + "&zoomLevel=" + str( args.zoom) + "&key=" + args.apikey from PIL import Image, ImageDraw, ImageFont size = ( args.size, args.size, ) perrow = args.numcols + args.dimension fnt = ImageFont.truetype('arialbd.ttf', 15) slots = len(pos) + args.dimension * args.dimension hei = max(args.dimension, slots // (args.numcols)) #print(hei); img = Image.new('RGB', (args.size * perrow, args.size * hei), color='white') dr = ImageDraw.Draw(img) i = args.dimension j = 0 num = 0 for token in pos: #API unterstützt nur 18 Marker if num == 18: if args.verbose > 0: print( 'INFO: more that 18 pictures, only 18 pictures are supported' ) break num += 1 timg = Image.open(token[3]) if (token[4] == Orientation.RIGHT_TOP): timg = timg.rotate(270, Image.NEAREST, expand=1) elif (token[4] == Orientation.RIGHT_BOTTOM): timg = timg.rotate(90, Image.NEAREST, expand=1) elif (token[4] == Orientation.LEFT_BOTTOM): timg = timg.rotate(180, Image.NEAREST, expand=1) timg.thumbnail(size) label = token[0][args.begin:(args.begin + args.amount)] if label == '': label = "{:03d}".format(1) #timg.show(); img.paste(timg, (i * args.size, j * args.size)) dr.rectangle(((i * args.size, j * args.size), (i * args.size + 35, j * args.size + 20)), fill='black') dr.text((i * args.size + 2, j * args.size + 2), label, font=fnt, fill=(255, 255, 255)) #dr.text((i*256+10,(1+j)*256-20), label, font=fnt,fill=(255,255,255)) i = i + 1 if (i == perrow): j = j + 1 i = 0 if (j < args.dimension): i = args.dimension #imgs.append(PIL.Image.open(token[3])); yy = token[1][0] + token[1][1] / 60 + token[1][2] / 3600 xx = token[2][0] + token[2][1] / 60 + token[2][2] / 3600 url = url + '&pushpin=' + str(xx) + "," + str(yy) + ';1;' + str( label) #img.save("C:/TEMP/out.jpg", "JPEG", quality=80, optimize=True, progressive=True) print('mapUrl = ' + url) import urllib.request urllib.request.urlretrieve(url, "map.jpg") im = Image.open("map.jpg") img.paste(im, (0, 0)) img.save(args.outfile, "JPEG", quality=80, optimize=True, progressive=True) if args.verbose > 0: Image.open(args.outfile).show() except KeyError as e: print(e) import traceback indent = len(program_name) * " " sys.stderr.write(program_name + ": " + repr(e) + "\n") sys.stderr.write(indent + " for help use --help") traceback.print_exc() return 2
def processFile(args): argob, path = args path = Path(path) file_info = { "creation": None, "file_prefix": "", "file_suffix": "", "file_content_type": "", "old_conflict": "", "dtpattern_in_path": False, "conflict_count": 0, "cleaned_file_name": "" } creation = None image_exif = None image_exif_date_error = False lower_suffix = path.suffix.lower() if lower_suffix in img_suffixes: file_info["file_content_type"] = "IMG" try: with path.open(mode='rb') as f: image_exif = Image(f) except Exception as exc: logger.debug("Exception while reading exif: %s" % exc) if not image_exif or not image_exif.has_exif: logger.debug("image has no exif data/is not compatible: %s", path) image_exif = None elif hasattr(image_exif, "datetime"): try: creation = \ dt.strptime(image_exif.datetime, "%Y:%m:%d %H:%M:%S") except ValueError: logger.warning("Invalid format: %s", image_exif.datetime) image_exif_date_error = True elif hasattr(image_exif, "datetime_original"): try: creation = \ dt.strptime( image_exif.datetime_original, "%Y:%m:%d %H:%M:%S" ) except ValueError: logger.warning("Invalid format: %s", image_exif.datetime_original) image_exif_date_error = True elif lower_suffix in mov_suffixes: file_info["file_content_type"] = "MOV" else: if not argob.prune: logger.info("unrecognized file: %s", path) elif argob.dry_run: logger.info("Would remove: %s (unrecognized)", path) else: path.unlink() return 1 if argob.conflict == "ignore": file_info["cleaned_file_name"] = path.stem else: # find conflict counter and hash conflictmatch = extract_conflict_pattern.match(path.stem).groupdict() file_info["cleaned_file_name"] = conflictmatch["unrelated"] if conflictmatch["conflict_hash"]: if argob.conflict == "hash": # if hash is found, one conflict is indicated file_info["conflict_count"] = 1 else: file_info["cleaned_file_name"] = "%s-%s" % ( file_info["cleaned_file_name"], conflictmatch["conflict_hash"]) # if hash and counter: conflict_count = counter + 1 # if counter: conflict_count = counter # if hash: conflict_count = 1 file_info["conflict_count"] += \ int(conflictmatch["conflict_counter"] or 0) # check and potential extract datetime info from filename dtnamematch = extraction_pattern.match(file_info["cleaned_file_name"]) if dtnamematch: dtnamematchg = dtnamematch.groupdict() file_info["file_prefix"] = dtnamematchg["prefix"] or "" file_info["file_suffix"] = dtnamematchg["suffix"] or "" file_info["dtpattern_in_path"] = True if not creation: logger.debug("extract time from path: %s", path) creation = dt(year=int(dtnamematchg["year"]), month=int(dtnamematchg["month"]), day=int(dtnamematchg["day"]), hour=int(dtnamematchg["hour"] or 0), minute=int(dtnamematchg["minute"] or 0), second=int(dtnamematchg["second"] or 0)) # still no creation time if not creation: logger.debug("extract time from st_ctime: %s", path) creation = dt.fromtimestamp(path.stat().st_ctime) file_info["creation"] = creation if image_exif_date_error: file_info["old_file_hash"] = generate_hash(path) if argob.dry_run: logger.info("Would fix: %s to %s, of %s", image_exif.datetime, creation.strftime("%Y:%m:%d %H:%M:%S"), path) else: image_exif.datetime = creation.strftime("%Y:%m:%d %H:%M:%S") image_exif.datetime_original = image_exif.datetime with path.open(mode='wb') as f: f.write(image_exif.get_file()) file_info["file_hash"] = generate_hash(path) if rename_file(argob, path, file_info): return 1 return 0
def test_add_to_scanner_image(): """Test adding metadata to a scanner-produced JPEG without any pre-existing APP1 or EXIF.""" image = Image( os.path.join(os.path.dirname(__file__), "scanner_without_app1.jpg")) assert not image.has_exif image.gps_latitude = (41.0, 29.0, 57.48) image.gps_latitude_ref = "N" image.gps_longitude = (81.0, 41.0, 39.84) image.gps_longitude_ref = "W" image.gps_altitude = 199.034 image.gps_altitude_ref = GpsAltitudeRef.ABOVE_SEA_LEVEL image.make = "Acme Scanner Company" image.model = "Scan-o-Matic 5000" image.datetime_original = "1999:12:31 23:49:12" image.datetime_digitized = "2020:07:11 10:11:37" image.brightness_value = 10.9876 # provides coverage for SRATIONAL image.user_comment = "This image was scanned in from an old photo album." # provides coverage for user comment assert image.has_exif assert image.gps_latitude == (41.0, 29.0, 57.48) assert image.gps_latitude_ref == "N" assert image.gps_longitude == (81.0, 41.0, 39.84) assert image.gps_longitude_ref == "W" assert image.gps_altitude == 199.034 assert image.gps_altitude_ref == GpsAltitudeRef.ABOVE_SEA_LEVEL assert image.make == "Acme Scanner Company" assert image.model == "Scan-o-Matic 5000" assert image.datetime_original == "1999:12:31 23:49:12" assert image.datetime_digitized == "2020:07:11 10:11:37" assert image.brightness_value == 10.9876 # provides coverage for SRATIONAL assert (image.user_comment == "This image was scanned in from an old photo album." ) # provides coverage for user comment segment_hex = (binascii.hexlify( image._segments["APP1"].get_segment_bytes()).decode("utf-8").upper()) assert "\n".join(textwrap.wrap(segment_hex, 90)) == ADD_TO_SCANNED_IMAGE_BASELINE
class TestModifyExif(unittest.TestCase): """Test cases for deleting EXIF attributes.""" def setUp(self): """Open sample image file in binary mode for use in test cases.""" grand_canyon = os.path.join(os.path.dirname(__file__), 'grand_canyon.jpg') with open(grand_canyon, 'rb') as image_file: self.image = Image(image_file) assert self.image.has_exif def test_delete_ascii_tags(self): """Verify deleting EXIF ASCII from the Image object and the hexadecimal equivalent.""" del self.image.make del self.image.model with self.assertRaisesRegex(AttributeError, "image does not have attribute make"): self.image.make with self.assertRaisesRegex(AttributeError, "image does not have attribute model"): self.image.model segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), DELETE_ASCII_TAGS_HEX_BASELINE) def test_delete_gps_tags(self): """Verify deleting EXIF geotags from the Image object and the hexadecimal equivalent.""" del self.image.gps_latitude del self.image.gps_longitude del self.image.gps_altitude with self.assertRaisesRegex( AttributeError, "image does not have attribute gps_latitude"): self.image.gps_latitude with self.assertRaisesRegex( AttributeError, "image does not have attribute gps_longitude"): self.image.gps_longitude with self.assertRaisesRegex( AttributeError, "image does not have attribute gps_altitude"): self.image.gps_altitude segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), DELETE_GEOTAG_HEX_BASELINE) def test_delete_method(self): """Test behavior when setting tags using the ``delete()`` method.""" self.image.delete("model") with self.assertRaisesRegex(AttributeError, "image does not have attribute model"): self.image.model def test_handle_unset_attribute(self): """Verify that accessing an attribute not present in an image raises an AttributeError.""" with self.assertRaisesRegex( AttributeError, "image does not have attribute light_source"): del self.image.light_source def test_index_deleter(self): """Test deleting attributes using index syntax.""" del self.image["model"] with self.assertRaisesRegex(AttributeError, "image does not have attribute model"): self.image.model def test_standard_delete(self): """Verify that writing and deleting non-EXIF attributes behave normally.""" self.image.dummy_attr = 123 assert self.image.dummy_attr == 123 del self.image.dummy_attr with self.assertRaisesRegex(AttributeError, "unknown image attribute dummy_attr"): self.image.dummy_attr
def __init__(self, path: Path, suffix: str) -> None: with open(path, 'rb') as f: self.image = Image(f) self.path = path self.suffix = suffix
def move_photo(my_photo): print ("Get the call") with open(my_photo, 'rb') as image_file: my_image = Image(image_file) try: my_datetime_temp = my_image.datetime except AttributeError: now = datetime.now() my_datetime_temp = '2222:22:22 '+str(random.randint(100000, 999999)) my_datetime = my_datetime_temp.replace(':', '') dt = my_datetime.split(' ') new_date = dt[0] new_time = dt[1] try: new_make_temp = my_image.make except AttributeError: new_make_temp = "NONE" new_make = new_make_temp.replace(' ', '-') try: new_model_temp = my_image.model except AttributeError: new_model_temp = "NONE" new_model = new_model_temp.replace(' ', '-') new_name = new_date + '_' + new_time + '-' + new_make + '-' +new_model new_JPG = new_name + '.JPG' print (new_name) try: os.mkdir('for_picasa/'+new_date) except OSError as error: print('The folder was already exist, no need to create one') if (path.exists('for_picasa/'+new_date+'/'+new_name+'.JPG')): new_JPG = new_name+'-1.JPG' print (new_JPG+' exists') if (path.exists('for_picasa/'+new_date+'/'+new_name+'-1.JPG')): new_JPG = new_name+'-2.JPG' print (new_JPG+' exists') if (path.exists('for_picasa/'+new_date+'/'+new_name+'-2.JPG')): new_JPG = new_name+'-3.JPG' print (new_JPG+' exists') if (path.exists('for_picasa/'+new_date+'/'+new_name+'-3.JPG')): new_JPG = new_name+'-4.JPG' print (new_JPG+' exists') os.rename(my_photo, new_JPG) shutil.move(new_JPG, 'for_picasa/'+new_date) print ('Moved ' + new_name + ' to directory ' + new_date)
class TestModifyExif(unittest.TestCase): """Test cases for modifying EXIF attributes.""" def setUp(self): """Open sample image file in binary mode for use in test cases.""" grand_canyon = os.path.join(os.path.dirname(__file__), 'grand_canyon.jpg') with open(grand_canyon, 'rb') as image_file: self.image = Image(image_file) assert self.image.has_exif def test_handle_unset_attribute(self): """Verify that accessing an attribute not present in an image raises an AttributeError.""" with self.assertRaisesRegex( AttributeError, "image does not have attribute light_source"): self.image.light_source = 0 def test_handle_ascii_too_long(self): """Verify that writing a longer string to an ASCII tag raises a ValueError.""" with self.assertRaisesRegex(ValueError, "string must be no longer than original"): self.image.model = "MyArtificiallySetCameraAttribute" def test_index_modifier(self): """Test modifying attributes using index syntax.""" self.image["model"] = "MyCamera" self.assertEqual(self.image.model, Baseline("""MyCamera""")) def test_modify_ascii_same_len(self): """Verify that writing a same length string to an ASCII tag updates the tag.""" self.image.model = "MyCamera" self.assertEqual(self.image.model, Baseline("""MyCamera""")) segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), MODIFY_ASCII_SAME_LEN_HEX_BASELINE) def test_modify_ascii_shorter(self): """Verify that writing a shorter string to an ASCII tag updates the tag.""" self.image.model = "MyCam" self.assertEqual(self.image.model, Baseline("""MyCam""")) segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), MODIFY_ASCII_SHORTER_HEX_BASELINE) def test_modify_orientation(self): """Verify that modifying the orientation (a short tag) updates the tag value as expected.""" assert self.image.orientation == 1 assert repr(self.image.orientation) == Baseline( """<Orientation.TOP_LEFT: 1>""") self.image.orientation = 6 assert self.image.orientation == 6 segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), ROTATED_GRAND_CANYON_HEX) def test_modify_rational(self): """Verify that modifying RATIONAL tags updates the tag values as expected.""" self.image.gps_altitude = 123.456789 self.assertEqual(str(self.image.gps_altitude), Baseline("""123.456789""")) self.image.gps_latitude = (41.0, 36.0, 33.786) self.assertEqual(str(self.image.gps_latitude), Baseline("""(41.0, 36.0, 33.786)""")) segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), MODIFY_RATIONAL_HEX_BASELINE) def test_modify_srational(self): """Verify that modifying a SRATIONAL tag updates the tag value as expected.""" self.image.brightness_value = -2.468 self.assertEqual(str(self.image.brightness_value), Baseline("""-2.468""")) segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), MODIFY_SRATIONAL_HEX_BASELINE) def test_set_method(self): """Test behavior when setting tags using the ``set()`` method.""" self.image.set("model", "MyCamera") self.assertEqual(self.image.model, Baseline("""MyCamera"""))
class TestModifyExif(unittest.TestCase): """Test cases for deleting EXIF attributes.""" def setUp(self): """Open sample image file in binary mode for use in test cases.""" grand_canyon = os.path.join(os.path.dirname(__file__), 'grand_canyon.jpg') with open(grand_canyon, 'rb') as image_file: self.image = Image(image_file) assert self.image.has_exif def test_delete_all_tags(self): """Verify deleting all EXIF tags from the Image object.""" self.image.delete_all() segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), DELETE_ALL_HEX_BASELINE) with TemporaryFile("w+b") as temporary_file_stream: temporary_file_stream.write(self.image.get_file()) temporary_file_stream.seek(0) reloaded_image = Image(temporary_file_stream) dunder_dir_text = '\n'.join(textwrap.wrap(repr(sorted(dir(reloaded_image))), 90)) self.assertEqual(dunder_dir_text, Baseline(""" ['<unknown EXIF tag 59932>', '_segments', 'delete', 'delete_all', 'get', 'get_file', 'get_thumbnail', 'has_exif', 'resolution_unit', 'x_resolution', 'y_resolution'] """)) def test_delete_ascii_tags(self): """Verify deleting EXIF ASCII from the Image object and the hexadecimal equivalent.""" del self.image.make del self.image.model with self.assertRaisesRegex(AttributeError, "image does not have attribute make"): self.image.make with self.assertRaisesRegex(AttributeError, "image does not have attribute model"): self.image.model segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), DELETE_ASCII_TAGS_HEX_BASELINE) def test_delete_gps_tags(self): """Verify deleting EXIF geotags from the Image object and the hexadecimal equivalent.""" del self.image.gps_latitude del self.image.gps_longitude del self.image.gps_altitude with self.assertRaisesRegex(AttributeError, "image does not have attribute gps_latitude"): self.image.gps_latitude with self.assertRaisesRegex(AttributeError, "image does not have attribute gps_longitude"): self.image.gps_longitude with self.assertRaisesRegex(AttributeError, "image does not have attribute gps_altitude"): self.image.gps_altitude segment_hex = self.image._segments['APP1'].get_segment_hex() self.assertEqual('\n'.join(textwrap.wrap(segment_hex, 90)), DELETE_GEOTAG_HEX_BASELINE) def test_delete_method(self): """Test behavior when setting tags using the ``delete()`` method.""" self.image.delete("model") with self.assertRaisesRegex(AttributeError, "image does not have attribute model"): self.image.model def test_handle_unset_attribute(self): """Verify that accessing an attribute not present in an image raises an AttributeError.""" with self.assertRaisesRegex(AttributeError, "image does not have attribute light_source"): del self.image.light_source def test_index_deleter(self): """Test deleting attributes using index syntax.""" del self.image["model"] with self.assertRaisesRegex(AttributeError, "image does not have attribute model"): self.image.model def test_standard_delete(self): """Verify that writing and deleting non-EXIF attributes behave normally.""" self.image.dummy_attr = 123 assert self.image.dummy_attr == 123 del self.image.dummy_attr with self.assertRaisesRegex(AttributeError, "unknown image attribute dummy_attr"): self.image.dummy_attr
from exif import Image with open('Computer-Password-Security-Hacker.jpg', 'rb') as image_file: my_image = Image(image_file) #print(my_image.has_exif) print(my_image.camera_owner_name)
while new_bear > 360: new_bear -= 360 lonref, lon2 = to_gps_latlon(new_lon, ('E', 'W')) latref, lat2 = to_gps_latlon(new_lat, ('N', 'S')) #print (latref,lat2,new_lat) if args.mask: image = cv2.bitwise_and(image, image, mask=mask) if args.crop_top + args.crop_bottom + args.crop_left + args.crop_right > 0: height, width, channels = image.shape image = image[args.crop_top:height - args.crop_bottom, args.crop_left:width - args.crop_right] cv2.imwrite("tmp.jpg", image) e_image = Image("tmp.jpg") #e_image.gps_latitude = lat2 #e_image.gps_latitude_ref = latref #e_image.gps_longitude = lon2 #e_image.gps_longitude_ref = lonref #e_image.gps_img_direction = new_bear #e_image.gps_dest_bearing = new_bear #e_image.make = make #e_image.model = model datetime_taken = datetime.fromtimestamp(new_ts + args.timezone * 3600) datetime_original = datetime_taken.strftime( DATETIME_STR_FORMAT) with open(
5: b'\x00', 6: (241175, 391), 7: ((19, 1), (8, 1), (40, 1)), 12: 'K', 13: (0, 1), 16: 'T', 17: (1017664, 4813), 23: 'T', 24: (1017664, 4813), 29: '2019:01:11', 31: (65, 1) } with open(im_path, 'rb') as image_file: im = Image(image_file) im.make = data['make'] im.model = data['model'] im.camera = data['camera'] im.GPSInfo = GPSInfo with open(new_im_name, 'wb') as new_image_file: new_image_file.write(im.get_file()) with open(new_im_name, 'rb') as image_file: imtest = Image(image_file) os.system('rm ' + im_path)
latlonitude = float(coordinate) degrees = floor(latlonitude) residuum = (latlonitude - degrees) * 60 minutes = floor(residuum) seconds = (residuum - minutes) * 60 return (degrees, minutes, seconds) if(len(names) < 4): print('USAGE: exifGPSimplant filename latitude [0-360) longitude [0 - 180)') exit(-1) else: (recipient, latitude, longitude) = names[1:4] with open(recipient, 'rb') as image_file: img = Image(image_file) img.gps_latitude = dd_GPS_dms(latitude) img.gps_longitude = dd_GPS_dms(longitude) #img.gps_altitude = 1200 # An orphan... print(img.gps_latitude, img.gps_longitude) with open(recipient, 'wb') as image_file: image_file.write(img.get_file()) ## Note the GPS tags format # 34°56'43.386"N 109°46'32.447"W ## Other locations... # https://www.gps-coordinates.net/gps-coordinates-converter
import exif from exif import Image #https://pypi.org/project/exif/ # open image as my_image with open('1.jpg', 'rb') as image_file: my_image = Image(image_file) # show all image attributes print(my_image.list_all()) ### show model attribute from my_image ##print(my_image.model) # set image attributes my_image.focal_length = 99 my_image.model = "iPhone 13" # print for testing print(">>", my_image.focal_length) # save modified image as modified_image.jpg with open('modified_image.jpg', 'wb') as new_image_file: new_image_file.write(my_image.get_file())
def __init__(self, img_path): with open(img_path, 'rb') as file: self.image = Exif(file)