3838from tempfile import TemporaryDirectory
3939import webbrowser
4040
41- from flask import Flask
41+ from flask import Flask , Response
4242from flask_cors import CORS
4343import imagehash
4444from jinja2 import FileSystemLoader , Environment
4747import pymongo
4848from termcolor import cprint
4949import pybktree
50+ import io
51+ import pyheif
5052
5153@contextmanager
5254def connect_to_db (db_conn_string = './db' ):
@@ -101,7 +103,7 @@ def get_image_files(path):
101103 def is_image (file_name ):
102104 # List mime types fully supported by Pillow
103105 full_supported_formats = ['gif' , 'jp2' , 'jpeg' , 'pcx' , 'png' , 'tiff' , 'x-ms-bmp' ,
104- 'x-portable-pixmap' , 'x-xbitmap' ]
106+ 'x-portable-pixmap' , 'x-xbitmap' , 'heic' ]
105107 try :
106108 mime = magic .from_file (file_name , mime = True )
107109 return mime .rsplit ('/' , 1 )[1 ] in full_supported_formats
@@ -115,25 +117,35 @@ def is_image(file_name):
115117 if is_image (file ):
116118 yield file
117119
120+ def hash_image (img ):
121+ image_size = get_image_size (img )
122+ capture_time = get_capture_time (img )
123+
124+ hashes = []
125+ # hash the image 4 times and rotate it by 90 degrees each time
126+ for angle in [ 0 , 90 , 180 , 270 ]:
127+ if angle > 0 :
128+ turned_img = img .rotate (angle , expand = True )
129+ else :
130+ turned_img = img
131+ hashes .append (str (imagehash .phash (turned_img )))
132+
133+ hashes = '' .join (sorted (hashes ))
134+ return hashes , image_size , capture_time
118135
119136def hash_file (file ):
120137 try :
121- hashes = []
122- img = Image .open (file )
138+ mime = magic .from_file (file , mime = True )
139+ if mime .rsplit ('/' , 1 )[1 ] == 'heic' :
140+ heif = pyheif .read_heif (open (file , 'rb' ))
141+ img = Image .frombytes (
142+ mode = heif .mode , size = heif .size , data = heif .data )
143+ else :
144+ img = Image .open (file )
123145
124146 file_size = get_file_size (file )
125- image_size = get_image_size (img )
126- capture_time = get_capture_time (img )
127147
128- # hash the image 4 times and rotate it by 90 degrees each time
129- for angle in [ 0 , 90 , 180 , 270 ]:
130- if angle > 0 :
131- turned_img = img .rotate (angle , expand = True )
132- else :
133- turned_img = img
134- hashes .append (str (imagehash .phash (turned_img )))
135-
136- hashes = '' .join (sorted (hashes ))
148+ hashes , image_size , capture_time = hash_image (img )
137149
138150 cprint ("\t Hashed {}" .format (file ), "blue" )
139151 return file , hashes , file_size , image_size , capture_time
@@ -346,6 +358,16 @@ def render(duplicates, current, total):
346358 def delete_picture_ (file_name , trash = trash ):
347359 return str (delete_picture (file_name , db , trash ))
348360
361+ @app .route ('/heic-transform/<everything:file_name>' , methods = ['GET' ])
362+ def transcode_heic_ (file_name ):
363+ heif_image = pyheif .read_heif (open (file_name , 'rb' ))
364+
365+ image = Image .frombytes (
366+ mode = heif_image .mode , size = heif_image .size , data = heif_image .data )
367+ encoded = io .BytesIO ()
368+ image .save (encoded , format = 'JPEG' )
369+ return Response (encoded .getvalue (), mimetype = 'image/jpeg' )
370+
349371 app .run ()
350372
351373
0 commit comments