diff --git a/coastsnap/fonts/LiberationMono.ttf b/coastsnap/fonts/LiberationMono.ttf new file mode 100644 index 0000000..1a39bc7 Binary files /dev/null and b/coastsnap/fonts/LiberationMono.ttf differ diff --git a/coastsnap/tag_registered.py b/coastsnap/tag_registered.py index 3f1c715..debf66b 100644 --- a/coastsnap/tag_registered.py +++ b/coastsnap/tag_registered.py @@ -2,10 +2,13 @@ from pathlib import Path import pandas as pd import os os.chdir(Path(__file__).parent.resolve()) -from utils import datenum_to_datetime, RegisteredImage +from utils import datenum_to_datetime, RegisteredImage, get_site_tide_data import openpyxl import scipy.io as sio from PIL import Image, ImageDraw +from loguru import logger +import argparse + ''' SCRIPT LOGIC @@ -18,49 +21,37 @@ For each site in Images Parent Directory: If yes, skip to the next site ''' +#-----------------------------------------------------------------------------# +# Get command-line arguments +parser = argparse.ArgumentParser() +parser.add_argument("--tag_deleted", action='store_true', required=False) +parser.add_argument("--overwrite", action='store_true', required=False) +parser.add_argument("--site", type=str, required=False) +args = parser.parse_args() #-----------------------------------------------------------------------------# -# Update this file path for Image Tagging - Tide Data -# Example: images_dir = '/Users/admin/OneDrive - UNSW/My files/CoastSnap/' +# Retrieve coastsnap/images directory set in coastsnap_sites.csv code_images_dir = str(Path(os.getcwd()).parent) sites_csv_path = os.path.join(code_images_dir, "coastsnap_sites.csv") - -# RETRIEVE IMAGES PARENT DIRECTORY IN coastsnap_sites.csv - coastsnap_sites_csv = pd.read_csv(sites_csv_path) images_parent_dir = coastsnap_sites_csv.parent_directory[0] images_dir = os.path.join(images_parent_dir, "Images") -#-----------------------------------------------------------------------------# - - -def get_site_tide_data(images_parent_dir, site): - - # Retrieve tide data for the given site - db = openpyxl.load_workbook(images_parent_dir + "/Database/CoastSnapDB.xlsx") - beach_data = db[site] - tide_filename = beach_data["B24"].value - - if tide_filename == 'NO_TIDE.mat': - return False - - tide_filename_pkl = tide_filename[:-4] + '.pkl' - tides_path = images_parent_dir + '/Tide Data/Tide_Data_Python/' + tide_filename_pkl - tides_df = pd.read_pickle(tides_path) - - return tides_df - +#-----------------------------------------------------------------------------# +# Tag image function def tag_image(image2tag): image = Image.open(image2tag.pathname) draw = ImageDraw.Draw(image) - image2tag.get_dimensions() # White Text Box - rect_height = image2tag.height/20 + if image2tag.large_filename: + rect_height = image2tag.height/13 + else: + rect_height = image2tag.height/20 # Create white text box draw.rectangle((0, 0, image2tag.width, rect_height), fill='white') @@ -75,62 +66,69 @@ def tag_image(image2tag): image.save(registered_path) #-----------------------------------------------------------------------------# -# This is the main function +# Main function (called below) - -image2tag = None - -for site in os.listdir(images_dir): # Loop through SITES - print(site) +def main(site): + i=0 site_complete = False # A flag to stop tagging images when found tide_data = False font = None + image2tag = None photoshop_path = images_dir +'/'+ site + '/Photoshop' try: # Check if site contains 'Processed' directory years_list = os.listdir(photoshop_path) years_list.reverse() except: # Site doesn't contain 'Processed'. Go to next site. - continue - for year in years_list: # Loop through YEARS + return + + # Loop through YEARS + for year in years_list: if site_complete: break year_path = photoshop_path + '/' + year image_list = os.listdir(year_path) image_list.reverse() - for image_filename in image_list: # Loop through IMAGES + # Loop through IMAGES + for image_filename in image_list: registered_year_path = year_path.replace('Photoshop', 'Registered') registered_image_path = registered_year_path + '/' + image_filename[:-4] + '_registered.jpg' if site not in image_filename: # Check the filename has the site in it continue - if os.path.isfile(registered_image_path): # Image already tagged. Go to next site. - site_complete = True; - if i == 0: - print(site + ": " + str(i) + " images tagged") - elif image2tag and image2tag.tide: - print(site + ": " + str(i) + " images tagged with tide") - else: - print(site + ": " + str(i) + " images tagged no tide") - break - - else: # Image not tagged. Tag it. - if not os.path.exists(registered_year_path): # Chech that registered/year directory exists - os.makedirs(registered_year_path) # if not, create it - i += 1 - pathname = os.path.join(year_path, image_filename) - image2tag = RegisteredImage(pathname, image_filename) # Create image object - if i == 1: # Retrieve Tide Data once for each site - tides_df = get_site_tide_data(images_parent_dir, site) - - font = image2tag.get_font() - if tides_df: image2tag.get_tide(tides_df) - image2tag.create_tag() + # Case: Image already tagged + if os.path.isfile(registered_image_path): + if args.tag_deleted: # If 'tag_deleted' = True, continue to next image + continue + elif args.overwrite: # If 'overwrite' = True, pass and tag image + pass + else: # Otherwise, stop tagging and go to the next site + site_complete = True; + if i == 0: + print(site + ": " + str(i) + " images tagged") + elif image2tag and image2tag.tide: + print(site + ": " + str(i) + " images tagged with tide") + else: + print(site + ": " + str(i) + " images tagged no tide") + return + + # Case: Image not tagged or 'overwrite' = True + if not os.path.exists(registered_year_path): # Chech that registered/year directory exists + os.makedirs(registered_year_path) # if not, create it + i += 1 + pathname = os.path.join(year_path, image_filename) + image2tag = RegisteredImage(pathname, image_filename) # Create image object + if i == 1: # Retrieve Tide Data once for each site + tides_df = get_site_tide_data(images_parent_dir, site) - tag_image(image2tag) + font = image2tag.get_font() + image2tag.get_dimensions() + if isinstance(tides_df, pd.DataFrame): image2tag.get_tide(tides_df) + image2tag.create_tag() + + tag_image(image2tag) - # No images previously tagged - # print result + # Case: All images tagged if not site_complete: if i == 0: print(site + ": " + str(i) + " images tagged") @@ -138,3 +136,15 @@ for site in os.listdir(images_dir): # Loop through SITES print(site + ": " + str(i) + " images tagged with tide") else: print(site + ": " + str(i) + " images tagged no tide") + +#-----------------------------------------------------------------------------# +# Calling the main function with the two cases + +if args.site: # Case 1: User specifies a site + main(args.site) +else: # Case 2: No site specified. Tag all images + for site in os.listdir(images_dir): + main(site) + + + diff --git a/coastsnap/utils.py b/coastsnap/utils.py index 2869a73..6ad9340 100644 --- a/coastsnap/utils.py +++ b/coastsnap/utils.py @@ -3,6 +3,8 @@ from datetime import datetime, timedelta import sys from time import strptime from PIL import Image, ImageFont +import pandas as pd +import openpyxl def divide_chunks(l, n): """ @@ -49,7 +51,23 @@ def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+ yield item show(i+1) print("\n", flush=True, file=out) + + +def get_site_tide_data(images_parent_dir, site): + + # Retrieve tide data for the given site + db = openpyxl.load_workbook(images_parent_dir + "/Database/CoastSnapDB.xlsx") + beach_data = db[site] + tide_filename = beach_data["B24"].value + if tide_filename == 'NO_TIDE.mat': + return False + + tide_filename_pkl = tide_filename[:-4] + '.pkl' + tides_path = images_parent_dir + '/Tide Data/Tide_Data_Python/' + tide_filename_pkl + tides_df = pd.read_pickle(tides_path) + + return tides_df class RegisteredImage(): @@ -77,6 +95,7 @@ class RegisteredImage(): self.width = None self.height = None self.font = None + self.large_filename = False def get_tide(self, tides_df): @@ -97,18 +116,33 @@ class RegisteredImage(): hour = self.hour.zfill(2) minute = self.minute.zfill(2) - if self.tide: + if self.tide: # Tag with tide data tide = self.tide if float(self.tide) >= 0: tide = '+' + self.tide - self.tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + + tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + + ' Time:' + hour + ':' + minute + + ' Tide:' + tide + 'm AHD' + + ' Contributor:' + self.contributor) + + if(self.font.getsize(tag)[0] > self.width): # Check if text is wider than the image + self.large_filename = True + tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + ' Time:' + hour + ':' + minute + - ' Tide:' + tide + 'm AHD' + - ' Contributor:' + self.contributor) - else: - self.tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + + ' Tide:' + tide + 'm AHD' + '\n' + + 'Contributor:' + self.contributor) + self.tag = tag + + else: # Tag without tide data + tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + ' Time:' + hour + ':' + minute + ' Contributor:' + self.contributor) + if(self.font.getsize(tag)[0] > self.width): # Check if text is wider than the image + self.large_filename = True + tag = ('Date:' + self.year + '/' + self.month + '/' + self.day + + ' Time:' + hour + ':' + minute + '\n' + + 'Contributor:' + self.contributor) + self.tag = tag def get_dimensions(self): image = Image.open(self.pathname) @@ -124,11 +158,15 @@ class RegisteredImage(): img_fraction = 0.95 else: img_fraction = 0.85 - font = ImageFont.truetype("fonts/Courier New Bold.ttf", fontsize) + font = ImageFont.truetype("fonts/LiberationMono.ttf", fontsize) generic_large_tag = "1641775682.Mon.Jan.10_11_48_02.AEDT.2022.byron.snap.KateThornborough123" while font.getsize(generic_large_tag)[0] < img_fraction*image.size[0]: # iterate until the text size is just larger than the criteria fontsize += 1 - font = ImageFont.truetype("fonts/Courier New Bold.ttf", fontsize) - self.font = ImageFont.truetype("fonts/Courier New Bold.ttf", fontsize) \ No newline at end of file + font = ImageFont.truetype("fonts/LiberationMono.ttf", fontsize) + self.font = ImageFont.truetype("fonts/LiberationMono.ttf", fontsize) + + + + \ No newline at end of file