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.

138 lines
4.9 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(items, pivot):
"""
This function will return the datetime in items
which is the closest to the date pivot
"""
return min(items, key=lambda x: abs(x - pivot))
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, site_tide_data, ts):
# 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(site_tide_data, img_datetime)
mat_index = site_tide_data.index(tide_date) # Retrieve the index of the .mat tide/time
mat_tide = round(ts[1][mat_index][0], 2) # Associated tide
#print('Image date/time: ' + date_string)
#print('Tide record: ' + str(tide_date))
self.tide = "{:.2f}".format(mat_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)