convert uploaded images to webp

This commit is contained in:
thomas girod 2024-09-01 19:05:54 +02:00
parent b3e59b3829
commit dd07c374d7
6 changed files with 41 additions and 34 deletions

View File

@ -234,10 +234,10 @@ Welcome to the wiki page!
skia_profile = SithFile( skia_profile = SithFile(
parent=profiles_root, parent=profiles_root,
name=name, name=name,
file=resize_image(Image.open(BytesIO(f.read())), 400, "JPEG"), file=resize_image(Image.open(BytesIO(f.read())), 400, "WEBP"),
owner=skia, owner=skia,
is_folder=False, is_folder=False,
mime_type="image/jpeg", mime_type="image/webp",
size=skia_profile_path.stat().st_size, size=skia_profile_path.stat().st_size,
) )
skia_profile.file.name = name skia_profile.file.name = name
@ -368,10 +368,10 @@ Welcome to the wiki page!
richard_profile = SithFile( richard_profile = SithFile(
parent=profiles_root, parent=profiles_root,
name=name, name=name,
file=resize_image(Image.open(BytesIO(f.read())), 400, "JPEG"), file=resize_image(Image.open(BytesIO(f.read())), 400, "WEBP"),
owner=richard, owner=richard,
is_folder=False, is_folder=False,
mime_type="image/jpeg", mime_type="image/webp",
size=richard_profile_path.stat().st_size, size=richard_profile_path.stat().st_size,
) )
richard_profile.file.name = name richard_profile.file.name = name
@ -853,10 +853,10 @@ Welcome to the wiki page!
sli_profile = SithFile( sli_profile = SithFile(
parent=profiles_root, parent=profiles_root,
name=name, name=name,
file=resize_image(Image.open(BytesIO(f.read())), 400, "JPEG"), file=resize_image(Image.open(BytesIO(f.read())), 400, "WEBP"),
owner=sli, owner=sli,
is_folder=False, is_folder=False,
mime_type="image/jpeg", mime_type="image/webp",
size=sli_profile_path.stat().st_size, size=sli_profile_path.stat().st_size,
) )
sli_profile.file.name = name sli_profile.file.name = name
@ -887,10 +887,10 @@ Welcome to the wiki page!
krophil_profile = SithFile( krophil_profile = SithFile(
parent=profiles_root, parent=profiles_root,
name=name, name=name,
file=resize_image(Image.open(BytesIO(f.read())), 400, "JPEG"), file=resize_image(Image.open(BytesIO(f.read())), 400, "WEBP"),
owner=krophil, owner=krophil,
is_folder=False, is_folder=False,
mime_type="image/jpeg", mime_type="image/webp",
size=krophil_profile_path.stat().st_size, size=krophil_profile_path.stat().st_size,
) )
krophil_profile.file.name = name krophil_profile.file.name = name
@ -1217,13 +1217,13 @@ Welcome to the wiki page!
parent=album, parent=album,
name=p.name, name=p.name,
file=resize_image( file=resize_image(
Image.open(BytesIO(p.read_bytes())), 1000, "JPEG" Image.open(BytesIO(p.read_bytes())), 1000, "WEBP"
), ),
owner=root, owner=root,
is_folder=False, is_folder=False,
is_in_sas=True, is_in_sas=True,
is_moderated=True, is_moderated=True,
mime_type="image/jpeg", mime_type="image/webp",
size=p.stat().st_size, size=p.stat().st_size,
) )
pict.file.name = p.name pict.file.name = p.name
@ -1252,10 +1252,10 @@ Welcome to the wiki page!
skia_profile = SithFile( skia_profile = SithFile(
parent=profiles_root, parent=profiles_root,
name=name, name=name,
file=resize_image(Image.open(BytesIO(f.read())), 400, "JPEG"), file=resize_image(Image.open(BytesIO(f.read())), 400, "WEBP"),
owner=skia, owner=skia,
is_folder=False, is_folder=False,
mime_type="image/jpeg", mime_type="image/webp",
size=skia_profile_path.stat().st_size, size=skia_profile_path.stat().st_size,
) )
skia_profile.file.name = name skia_profile.file.name = name

View File

@ -164,7 +164,7 @@
/* Stop camera */ /* Stop camera */
this.video.pause() this.video.pause()
this.video.srcObject.getTracks().forEach((track) => { this.video.srcObject.getTracks().forEach((track) => {
if (track.readyState == 'live') { if (track.readyState === 'live') {
track.stop(); track.stop();
} }
}); });
@ -172,8 +172,8 @@
canvas.toBlob((blob) => { canvas.toBlob((blob) => {
let file = new File( let file = new File(
[blob], [blob],
"{% trans %}captured{% endtrans %}.png", "{% trans %}captured{% endtrans %}.webp",
{ type: "image/jpeg" }, { type: "image/webp" },
); );
let list = new DataTransfer(); let list = new DataTransfer();

View File

@ -102,13 +102,17 @@ def scale_dimension(width, height, long_edge):
def resize_image(im, edge, img_format): def resize_image(im, edge, img_format):
(w, h) = im.size (w, h) = im.size
(width, height) = scale_dimension(w, h, long_edge=edge) (width, height) = scale_dimension(w, h, long_edge=edge)
img_format = img_format.upper()
content = BytesIO() content = BytesIO()
# use the lanczos filter for antialiasing and discard the alpha channel # use the lanczos filter for antialiasing and discard the alpha channel
im = im.resize((width, height), Resampling.LANCZOS).convert("RGB") im = im.resize((width, height), Resampling.LANCZOS)
if img_format == "JPEG":
# converting an image with an alpha channel to jpeg would cause a crash
im = im.convert("RGB")
try: try:
im.save( im.save(
fp=content, fp=content,
format=img_format.upper(), format=img_format,
quality=90, quality=90,
optimize=True, optimize=True,
progressive=True, progressive=True,
@ -117,7 +121,7 @@ def resize_image(im, edge, img_format):
PIL.ImageFile.MAXBLOCK = im.size[0] * im.size[1] PIL.ImageFile.MAXBLOCK = im.size[0] * im.size[1]
im.save( im.save(
fp=content, fp=content,
format=img_format.upper(), format=img_format,
quality=90, quality=90,
optimize=True, optimize=True,
progressive=True, progressive=True,

View File

@ -12,6 +12,7 @@
# OR WITHIN THE LOCAL FILE "LICENSE" # OR WITHIN THE LOCAL FILE "LICENSE"
# #
# #
import mimetypes
from urllib.parse import quote, urljoin from urllib.parse import quote, urljoin
# This file contains all the views that concern the page model # This file contains all the views that concern the page model
@ -77,7 +78,7 @@ def send_file(
raise Http404 raise Http404
with open(filepath, "rb") as filename: with open(filepath, "rb") as filename:
response.content = FileWrapper(filename) response.content = FileWrapper(filename)
response["Content-Type"] = f.mime_type response["Content-Type"] = mimetypes.guess_type(filepath)[0]
response["Last-Modified"] = http_date(f.date.timestamp()) response["Last-Modified"] = http_date(f.date.timestamp())
response["Content-Length"] = filepath.stat().st_size response["Content-Length"] = filepath.stat().st_size
return response return response

View File

@ -239,10 +239,6 @@ class UserProfileForm(forms.ModelForm):
"quote": forms.Textarea, "quote": forms.Textarea,
} }
def generate_name(self, field_name, f):
field_name = field_name[:-4]
return field_name + str(self.instance.id) + "." + f.content_type.split("/")[-1]
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
@ -278,11 +274,11 @@ class UserProfileForm(forms.ModelForm):
im = Image.open(BytesIO(f.read())) im = Image.open(BytesIO(f.read()))
new_file = SithFile( new_file = SithFile(
parent=parent, parent=parent,
name=self.generate_name(field, f), name=f"{field.removesuffix('_pict')}_{self.instance.id}.webp",
file=resize_image(im, 400, f.content_type.split("/")[-1]), file=resize_image(im, 400, "webp"),
owner=self.instance, owner=self.instance,
is_folder=False, is_folder=False,
mime_type=f.content_type, mime_type="image/wepb",
size=f.size, size=f.size,
moderator=self.instance, moderator=self.instance,
is_moderated=True, is_moderated=True,

View File

@ -110,19 +110,25 @@ class Picture(SasFile):
im = exif_auto_rotate(im) im = exif_auto_rotate(im)
except: except:
pass pass
file = resize_image(im, max(im.size), self.mime_type.split("/")[-1]) # convert the compressed image and the thumbnail into webp
thumb = resize_image(im, 200, self.mime_type.split("/")[-1]) # The original image keeps its original type, because it's not
compressed = resize_image(im, 1200, self.mime_type.split("/")[-1]) # meant to be shown on the website, but rather to keep the real image
# for less frequent cases (like downloading the pictures of an user)
extension = self.mime_type.split("/")[-1]
file = resize_image(im, max(im.size), extension)
thumb = resize_image(im, 200, "webp")
compressed = resize_image(im, 1200, "webp")
if overwrite: if overwrite:
self.file.delete() self.file.delete()
self.thumbnail.delete() self.thumbnail.delete()
self.compressed.delete() self.compressed.delete()
new_extension_name = self.name.removesuffix(extension) + "webp"
self.file = file self.file = file
self.file.name = self.name self.file.name = self.name
self.thumbnail = thumb self.thumbnail = thumb
self.thumbnail.name = self.name self.thumbnail.name = new_extension_name
self.compressed = compressed self.compressed = compressed
self.compressed.name = self.name self.compressed.name = new_extension_name
self.save() self.save()
def rotate(self, degree): def rotate(self, degree):
@ -224,9 +230,9 @@ class Album(SasFile):
.first() .first()
) )
if p and p.file: if p and p.file:
im = Image.open(BytesIO(p.file.read())) image = resize_image(Image.open(BytesIO(p.file.read())), 200, "webp")
self.file = resize_image(im, 200, "jpeg") self.file = image
self.file.name = self.name + "/thumb.jpg" self.file.name = f"{self.name}/thumb.webp"
self.save() self.save()