2
0
mirror of https://expo.survex.com/repositories/troggle/.git synced 2026-01-24 15:51:44 +00:00

re-inserted GPS into re-scaled images

This commit is contained in:
2025-02-10 23:34:45 +00:00
parent f4afa0c672
commit 91d8d33e95

View File

@@ -39,7 +39,14 @@ def get_dir(path):
else:
return ""
def insert_gps_data(image_path, gps_data):
"""Function to insert GPS data into the resized image
"""
exif_dict = piexif.load(image_path)
exif_dict['GPS'] = gps_data
exif_bytes = piexif.dump(exif_dict)
piexif.insert(exif_bytes, image_path)
def image_selector(request, path):
"""Returns available images
called from
@@ -70,7 +77,9 @@ def image_selector(request, path):
def reorient_image(img, exif_dict):
if piexif.ImageIFD.Orientation in exif_dict["0th"]:
print(exif_dict)
# print(f"reorient_image(): found ImageIFD.Orientation in 0th ")
# for ifd in exif_dict:
# print(f"reorient_image(): \"{ifd}\"\n {exif_dict[ifd]} ")
orientation = exif_dict["0th"].pop(piexif.ImageIFD.Orientation)
if orientation == 2:
@@ -92,45 +101,51 @@ def reorient_image(img, exif_dict):
@login_required_if_public
def new_image_form(request, path):
"""Manages a form to upload new images"""
"""Manages a form to upload new images
exif_dict = piexif.load(im.info["exif"])
exif_dict = {"0th":zeroth_ifd, "Exif":exif_ifd, "GPS":gps_ifd}
The "Exif.Image.NewSubfileType" tag (ID 41729) serves to identify
the type of image or subfile data contained in the image file
0: full resolution, 1: reduced resolution
"""
directory = get_dir(path)
print(f"new_image_form(): {directory=} {path=}")
editor = get_cookie(request)
if request.method == "POST":
print(f"new_image_form(): POST ")
# print(f"new_image_form(): POST ")
form = NewWebImageForm(request.POST, request.FILES, directory=directory)
if form.is_valid():
print(f"new_image_form(): form is valid ")
print(f"new_image_form(): files: {request.FILES['file_']}")
# print(f"new_image_form(): form is valid ")
editor = form.cleaned_data["who_are_you"]
editor = git_string(editor)
f = request.FILES["file_"]
binary_data = io.BytesIO()
for chunk in f.chunks():
binary_data.write(chunk)
print(f"new_image_form(): binary chnks written")
i = Image.open(binary_data)
print(f"new_image_form(): {i=}")
if "exif" in i.info:
print(f"new_image_form(): exif: {i=}")
exif_dict = piexif.load(i.info["exif"])
gps_data = exif_dict['GPS']
# print(f"new_image_form() EXIF loaded from {f.name}\n {gps_data=}")
i = reorient_image(i, exif_dict)
exif_dict['Exif'][41729] = b'1'
exif_dict['Exif'][41729] = b'1' # I am not sure this should be binary..
# can crash here with bad exif data
try:
# This is never written back into the images ?!!
exif = piexif.dump(exif_dict)
# int(f"new_image_form() After DUMP {exif=}")
except:
exif = None
else:
exif = None
print(f"new_image_form(): No exif problems")
width, height = i.size
print(f"new_image_form(): {i.size=}")
# print(f"new_image_form(): {i.size=}")
if width > MAX_IMAGE_WIDTH or height > MAX_IMAGE_HEIGHT:
print(f"new_image_form(): rescaling ")
scale = max(width / MAX_IMAGE_WIDTH, height / MAX_IMAGE_HEIGHT)
print(f"new_image_form(): rescaling {scale=}")
try:
@@ -143,10 +158,20 @@ def new_image_form(request, path):
thumbnail = i.resize((int(width / tscale), int(height / tscale)), Image.LANCZOS)
ib = io.BytesIO()
i = i.convert('RGB')
i.save(ib, format="jpeg", quality = 75)
exif_dict = piexif.load(i.info["exif"])
exif_dict['GPS'] = gps_data # saved from before
exif_bytes = piexif.dump(exif_dict)
ib = io.BytesIO()
i.save(ib, format='JPEG', quality = 85, exif=exif_bytes)
tb = io.BytesIO()
thumbnail = thumbnail.convert('RGB')
thumbnail.save(tb, format="jpeg", quality = 70)
exif_dict = piexif.load(thumbnail.info["exif"])
exif_dict['GPS'] = gps_data # saved from before
exif_bytes = piexif.dump(exif_dict)
thumbnail.save(tb, format='JPEG', quality = 70, exif=exif_bytes)
image_rel_path, thumb_rel_path, desc_rel_path = form.get_rel_paths()
print(f"new_image_form(): \n {image_rel_path=}\n {thumb_rel_path=}\n {desc_rel_path=}")
image_page_template = loader.get_template("image_page_template.html")
@@ -187,12 +212,12 @@ def new_image_form(request, path):
{"thumbnail_url": f"/{thumb_rel_path}", "page_url": f"/{desc_rel_path}"}, request
)
j_response = JsonResponse({"html": html_snippet})
j_response.set_cookie('editor_id', editor, max_age=COOKIE_MAX_AGE) # does not seem to work updating who_are_you cookie
j_response.set_cookie('editor_id', editor, max_age=COOKIE_MAX_AGE) # does NOT seem to work updating who_are_you cookie
return j_response
else:
print(f"new_image_form(): not POST ")
# print(f"new_image_form(): not POST ")
form = NewWebImageForm(directory=directory, initial={"who_are_you":editor})
print(f"new_image_form(): POST and not POST ")
# print(f"new_image_form(): POST and not POST ")
template = loader.get_template("new_image_form.html")
htmlform = template.render({"form": form, "path": path}, request)
return JsonResponse({"form": htmlform})
@@ -250,7 +275,7 @@ class NewWebImageForm(forms.Form):
class HTMLarea(forms.Textarea):
"""This is called from CaveForm in core/forms.py which is called from core/views/caves.py when editing a cave description
(and similarly for Entrance Descriptions). It is alls called from core/views/expo.py when editing expo (i.e. handbook) pages.
(and similarly for Entrance Descriptions). It is also called from core/views/expo.py when editing expo (i.e. handbook) pages.
"""
template_name = "widgets/HTMLarea.html"