Image upload polishing and webp

This commit is contained in:
Andrew Godwin 2022-12-04 10:46:41 -07:00
parent ffda9c4913
commit c3d4d0f547
4 changed files with 44 additions and 15 deletions

View File

@ -158,7 +158,7 @@ class ImageUpload(FormView):
def clean_image(self): def clean_image(self):
value = self.cleaned_data["image"] value = self.cleaned_data["image"]
if value.size > 1024 * 1024 * 1: if value.size > 1024 * 1024 * 10:
# Erase the file from our data to stop trying to show it again # Erase the file from our data to stop trying to show it again
self.files = {} self.files = {}
raise forms.ValidationError("File must be 10MB or less") raise forms.ValidationError("File must be 10MB or less")
@ -169,21 +169,30 @@ class ImageUpload(FormView):
def form_valid(self, form): def form_valid(self, form):
# Make a PostAttachment # Make a PostAttachment
thumbnail_file = resize_image(form.cleaned_data["image"], size=(400, 225)) main_file = resize_image(
form.cleaned_data["image"],
size=(2000, 2000),
cover=False,
)
thumbnail_file = resize_image(
form.cleaned_data["image"],
size=(400, 225),
cover=True,
)
attachment = PostAttachment.objects.create( attachment = PostAttachment.objects.create(
blurhash=blurhash_image(thumbnail_file), blurhash=blurhash_image(thumbnail_file),
mimetype=form.cleaned_data["image"].image.get_format_mimetype(), mimetype="image/webp",
width=form.cleaned_data["image"].image.width, width=main_file.image.width,
height=form.cleaned_data["image"].image.height, height=main_file.image.height,
name=form.cleaned_data.get("description"), name=form.cleaned_data.get("description"),
state=PostAttachmentStates.fetched, state=PostAttachmentStates.fetched,
) )
attachment.file.save( attachment.file.save(
form.cleaned_data["image"].name, main_file.name,
form.cleaned_data["image"], main_file,
) )
attachment.thumbnail.save( attachment.thumbnail.save(
form.cleaned_data["image"].name, thumbnail_file.name,
thumbnail_file, thumbnail_file,
) )
attachment.save() attachment.save()

View File

@ -5,16 +5,31 @@ from django.core.files import File
from PIL import Image, ImageOps from PIL import Image, ImageOps
def resize_image(image: File, *, size: tuple[int, int]) -> File: def resize_image(
image: File,
*,
size: tuple[int, int],
cover=True,
keep_format=False,
) -> File:
""" """
Resizes an image to fit insize the given size (cropping one dimension Resizes an image to fit insize the given size (cropping one dimension
to fit if needed) to fit if needed)
""" """
with Image.open(image) as img: with Image.open(image) as img:
if cover:
resized_image = ImageOps.fit(img, size) resized_image = ImageOps.fit(img, size)
else:
resized_image = ImageOps.contain(img, size)
new_image_bytes = io.BytesIO() new_image_bytes = io.BytesIO()
resized_image.save(new_image_bytes, format=img.format) if keep_format:
return File(new_image_bytes) resized_image.save(new_image_bytes, format=image.format)
file = File(new_image_bytes)
else:
resized_image.save(new_image_bytes, format="webp")
file = File(new_image_bytes, name="image.webp")
file.image = resized_image
return file
def blurhash_image(image) -> str: def blurhash_image(image) -> str:

View File

@ -610,7 +610,8 @@ form .buttons {
margin: -20px 0 15px 0; margin: -20px 0 15px 0;
} }
form p+.buttons { form p+.buttons,
form fieldset .buttons {
margin-top: 0; margin-top: 0;
} }
@ -618,6 +619,10 @@ form .button.add-image {
margin: 10px 0 10px 0; margin: 10px 0 10px 0;
} }
form legend+.button.add-image {
margin-top: 0px;
}
form progress { form progress {
display: none; display: none;
width: 100%; width: 100%;

View File

@ -5,7 +5,7 @@
{{ attachment.name|default:"(no description)" }} {{ attachment.name|default:"(no description)" }}
</p> </p>
<div class="buttons"> <div class="buttons">
<a class="button delete left" _="on click remove closest .uploaded_image">Remove</a> <a class="button delete left" _="on click remove closest .uploaded-image">Remove</a>
</div> </div>
</div> </div>
{% if request.htmx %} {% if request.htmx %}
@ -13,7 +13,7 @@
hx-get='{% url "compose_image_upload" %}' hx-get='{% url "compose_image_upload" %}'
hx-target="this" hx-target="this"
hx-swap="outerHTML" hx-swap="outerHTML"
_="on load if beep! length of beep! <.uploaded-image/> > 3 then hide me"> _="on load if length of <.uploaded-image/> > 3 then hide me">
Add Image Add Image
</a> </a>
{% endif %} {% endif %}