You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

134 lines
4.8 KiB
Python

import numpy as np
from datetime import datetime, timedelta
import sys
from time import strptime
from PIL import Image, ImageFont
def divide_chunks(l, n):
"""
Splits a list into chunks of length n. Used to process the images in chunks.
"""
for i in range(0, len(l), n):
yield l[i : i + n]
# Sourced from https://gist.github.com/victorkristof/b9d794fe1ed12e708b9d
def datenum_to_datetime(datenum):
"""
Convert Matlab datenum into Python datetime.
:param datenum: Date in datenum format
:return: Datetime object corresponding to datenum.
"""
days = datenum % 1
hours = days % 1 * 24
minutes = hours % 1 * 60
seconds = np.round(minutes % 1 * 60)
return datetime.fromordinal(int(datenum)) \
+ timedelta(days=int(days)) \
+ timedelta(hours=int(hours)) \
+ timedelta(minutes=int(minutes)) \
+ timedelta(seconds=int(seconds)) \
- timedelta(days=366)
# Sourced from https://stackoverflow.com/questions/32237862/find-the-closest-date-to-a-given-date
def nearest(all_dates, target_date_raw):
abs_deltas_from_target_date = np.absolute(all_dates - target_date_raw)
index_of_min_delta_from_target_date = np.argmin(abs_deltas_from_target_date)
closest_date = all_dates[index_of_min_delta_from_target_date]
return closest_date
def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+
count = len(it)
def show(j):
x = int(size*j/count)
print("{}[{}{}] {}/{}".format(prefix, u"#"*x, "."*(size-x), j, count),
end='\r', file=out, flush=True)
show(0)
for i, item in enumerate(it):
yield item
show(i+1)
print("\n", flush=True, file=out)
class RegisteredImage():
def __init__(self, pathname, filename):
self.pathname = pathname
self.filename = filename
filename_list = filename.split(".")
date = filename_list[3].split("_")
if 'snap' in filename_list:
self.contributor = filename_list[8] # Mitch filename format
else:
self.contributor = filename_list[6] # Leaman filename format
self.site = filename_list[6]
self.posix_time = filename_list[0]
self.timezone = filename_list[4]
self.year = filename_list[5]
self.month = '{:02d}'.format(strptime(filename_list[2],'%b').tm_mon) # Ensure 2-digit format
self.day = date[0]
self.hour = date[1]
self.minute = date[2]
self.second = date[3]
self.tide = None
self.tag = None
self.width = None
self.height = None
self.font = None
def get_tide(self, tides_df):
# Account for daylight savings
# ASSUMPTION: All .mat tide files are either AEST or AEDT
if self.timezone == 'AEDT':
self.hour = str(int(self.hour) - 1)
date_string = self.year + '-' + self.month + '-' + self.day + ' ' + self.hour + ':' + self.minute + ':' + self.second
img_datetime = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S") # Image date/time as a datetime object
tide_date = nearest(tides_df['time'], img_datetime)
tide = tides_df.loc[tides_df['time'] == tide_date, 'tide level']
tide = tide.iloc[0]
self.tide = "{:.2f}".format(tide)
def create_tag(self):
# Create image tag
hour = self.hour.zfill(2)
minute = self.minute.zfill(2)
if self.tide:
tide = self.tide
if float(self.tide) >= 0:
tide = '+' + self.tide
self.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 +
' Time:' + hour + ':' + minute +
' Contributor:' + self.contributor)
def get_dimensions(self):
image = Image.open(self.pathname)
# White Text Box
self.width, self.height = image.size
def get_font(self):
image = Image.open(self.pathname)
fontsize = 1
if self.tide:
img_fraction = 0.95
else:
img_fraction = 0.85
font = ImageFont.truetype("fonts/Courier New Bold.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)