Image upload polishing and webp
This commit is contained in:
		
							parent
							
								
									ffda9c4913
								
							
						
					
					
						commit
						c3d4d0f547
					
				@ -158,7 +158,7 @@ class ImageUpload(FormView):
 | 
			
		||||
 | 
			
		||||
        def clean_image(self):
 | 
			
		||||
            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
 | 
			
		||||
                self.files = {}
 | 
			
		||||
                raise forms.ValidationError("File must be 10MB or less")
 | 
			
		||||
@ -169,21 +169,30 @@ class ImageUpload(FormView):
 | 
			
		||||
 | 
			
		||||
    def form_valid(self, form):
 | 
			
		||||
        # 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(
 | 
			
		||||
            blurhash=blurhash_image(thumbnail_file),
 | 
			
		||||
            mimetype=form.cleaned_data["image"].image.get_format_mimetype(),
 | 
			
		||||
            width=form.cleaned_data["image"].image.width,
 | 
			
		||||
            height=form.cleaned_data["image"].image.height,
 | 
			
		||||
            mimetype="image/webp",
 | 
			
		||||
            width=main_file.image.width,
 | 
			
		||||
            height=main_file.image.height,
 | 
			
		||||
            name=form.cleaned_data.get("description"),
 | 
			
		||||
            state=PostAttachmentStates.fetched,
 | 
			
		||||
        )
 | 
			
		||||
        attachment.file.save(
 | 
			
		||||
            form.cleaned_data["image"].name,
 | 
			
		||||
            form.cleaned_data["image"],
 | 
			
		||||
            main_file.name,
 | 
			
		||||
            main_file,
 | 
			
		||||
        )
 | 
			
		||||
        attachment.thumbnail.save(
 | 
			
		||||
            form.cleaned_data["image"].name,
 | 
			
		||||
            thumbnail_file.name,
 | 
			
		||||
            thumbnail_file,
 | 
			
		||||
        )
 | 
			
		||||
        attachment.save()
 | 
			
		||||
 | 
			
		||||
@ -5,16 +5,31 @@ from django.core.files import File
 | 
			
		||||
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
 | 
			
		||||
    to fit if needed)
 | 
			
		||||
    """
 | 
			
		||||
    with Image.open(image) as img:
 | 
			
		||||
        resized_image = ImageOps.fit(img, size)
 | 
			
		||||
        if cover:
 | 
			
		||||
            resized_image = ImageOps.fit(img, size)
 | 
			
		||||
        else:
 | 
			
		||||
            resized_image = ImageOps.contain(img, size)
 | 
			
		||||
        new_image_bytes = io.BytesIO()
 | 
			
		||||
        resized_image.save(new_image_bytes, format=img.format)
 | 
			
		||||
        return File(new_image_bytes)
 | 
			
		||||
        if keep_format:
 | 
			
		||||
            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:
 | 
			
		||||
 | 
			
		||||
@ -610,7 +610,8 @@ form .buttons {
 | 
			
		||||
    margin: -20px 0 15px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
form p+.buttons {
 | 
			
		||||
form p+.buttons,
 | 
			
		||||
form fieldset .buttons {
 | 
			
		||||
    margin-top: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -618,6 +619,10 @@ form .button.add-image {
 | 
			
		||||
    margin: 10px 0 10px 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
form legend+.button.add-image {
 | 
			
		||||
    margin-top: 0px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
form progress {
 | 
			
		||||
    display: none;
 | 
			
		||||
    width: 100%;
 | 
			
		||||
 | 
			
		||||
@ -5,7 +5,7 @@
 | 
			
		||||
        {{ attachment.name|default:"(no description)" }}
 | 
			
		||||
    </p>
 | 
			
		||||
    <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>
 | 
			
		||||
{% if request.htmx %}
 | 
			
		||||
@ -13,7 +13,7 @@
 | 
			
		||||
    hx-get='{% url "compose_image_upload" %}'
 | 
			
		||||
    hx-target="this"
 | 
			
		||||
    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
 | 
			
		||||
</a>
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user