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
138 lines
4.9 KiB
Python
2 years ago
|
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)
|