diff --git a/pflaenzli/pflaenzli/utils/compress_image.py b/pflaenzli/pflaenzli/utils/compress_image.py new file mode 100644 index 0000000..d025f67 --- /dev/null +++ b/pflaenzli/pflaenzli/utils/compress_image.py @@ -0,0 +1,37 @@ +import sys +from io import BytesIO +from PIL import Image + +from django.core.files.uploadedfile import InMemoryUploadedFile +from pflaenzli_django.settings import IMAGE_MAX_SIZE, IMAGE_QUALITY + + +def compress_image(image, path): + tmp_img = Image.open(image) + fmt = tmp_img.format + + if fmt not in ['JPEG', 'PNG']: + raise TypeError(f'Invalid image format: {fmt}') + + width, height = tmp_img.size + compressed_width, compressed_height = get_compressed_size(width, height) + + tmp_img_resized = tmp_img.resize((compressed_width, compressed_height)) + + outputIoStream = BytesIO() + tmp_img_resized.save(outputIoStream, format=fmt, quality=IMAGE_QUALITY) + outputIoStream.seek(0) + return InMemoryUploadedFile(file=outputIoStream, field_name='ImageField', + content_type=f'image/{fmt.lower()}', name=path, size=sys.getsizeof(outputIoStream), + charset=None) + + +def get_compressed_size(width, height): + if width > height: + compressed_width = min(width, IMAGE_MAX_SIZE) + compressed_height = int(compressed_width * (height / width)) + else: + compressed_height = min(height, IMAGE_MAX_SIZE) + compressed_width = int(compressed_height * (width / height)) + + return compressed_width, compressed_height diff --git a/pflaenzli/pflaenzli/views.py b/pflaenzli/pflaenzli/views.py index 67db9da..83d5ab5 100644 --- a/pflaenzli/pflaenzli/views.py +++ b/pflaenzli/pflaenzli/views.py @@ -15,6 +15,7 @@ from .models import PflaenzliUser, Offer, Wish from .mail import send_offer_email from .upload import generate_unique_filename from .utils.distance import calculate_distance, filter_by_distance +from .utils.compress_image import compress_image def list_offers(request, filters=None): @@ -37,6 +38,7 @@ def create_offer(request): if form.is_valid(): offer = form.save(commit=False) offer.image.name = generate_unique_filename(form.cleaned_data['image'].name) + offer.image = compress_image(offer.image, offer.image.name) offer.user = request.user offer.title = offer.title.title() offer.save() @@ -89,6 +91,7 @@ def offer_edit(request, offer_id): offer = form.save(commit=False) if 'image' in request.FILES: offer.image.name = generate_unique_filename(form.cleaned_data['image'].name) + offer.image = compress_image(offer.image, offer.image.name) else: offer.image = offer.image offer.user = request.user diff --git a/pflaenzli/pflaenzli_django/settings.py b/pflaenzli/pflaenzli_django/settings.py index f79baac..c7efcf5 100644 --- a/pflaenzli/pflaenzli_django/settings.py +++ b/pflaenzli/pflaenzli_django/settings.py @@ -180,3 +180,8 @@ FRC_CAPTCHA_VERIFICATION_URL = 'https://api.friendlycaptcha.com/api/v1/siteverif # Loco translation managment LOCO_API_KEY = os.getenv('LOCO_API_KEY') + + +# Image compression settings +IMAGE_MAX_SIZE = 1500 # Long edge size +IMAGE_QUALITY = 75 # 0-100%