Use shortpixel to compress and resize images
This commit is contained in:
parent
9f6ffcb1a3
commit
57c1fe1ce8
3 changed files with 58 additions and 11 deletions
|
@ -1,6 +1,9 @@
|
|||
import json
|
||||
import tempfile
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
from django.conf import settings
|
||||
from django.core.files import File
|
||||
from django.db import models
|
||||
from PIL import Image
|
||||
|
@ -15,24 +18,63 @@ class Attachment(models.Model):
|
|||
if self.processed_file:
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
if self.id is None:
|
||||
super().save(*args, **kwargs)
|
||||
try:
|
||||
image = Image.open(self.original_file.path)
|
||||
except IOError:
|
||||
return self.save(*args, **kwargs)
|
||||
max_width = 640
|
||||
if image.width > max_width:
|
||||
ratio = image.height / image.width
|
||||
height = round(max_width * ratio)
|
||||
output = image.resize((max_width, height))
|
||||
else:
|
||||
output = image.copy()
|
||||
current_path = Path(image.filename)
|
||||
return super().save(*args, **kwargs)
|
||||
|
||||
# Submit job to shortpixel
|
||||
base_data = {
|
||||
"key": settings.SHORTPIXEL_API_KEY,
|
||||
"plugin_version": "gabno",
|
||||
"wait": 20,
|
||||
}
|
||||
post_data = {
|
||||
"lossy": 1,
|
||||
"resize": 3,
|
||||
"resize_width": 640,
|
||||
"resize_height": 10000,
|
||||
"file_paths": json.dumps(
|
||||
[f"{self.original_file.name}:{self.original_file.path}"]
|
||||
),
|
||||
}
|
||||
data = {**base_data, **post_data}
|
||||
url = "https://api.shortpixel.com/v2/post-reducer.php"
|
||||
with open(self.original_file.path, "rb") as original_file:
|
||||
response = requests.post(
|
||||
url=url, data=data, files={self.original_file.name: original_file}
|
||||
)
|
||||
res = response.json()
|
||||
res_data = res[0]
|
||||
|
||||
# Loop until it's done
|
||||
post_data = {
|
||||
"key": settings.SHORTPIXEL_API_KEY,
|
||||
"plugin_version": "gabno",
|
||||
"wait": 20,
|
||||
"file_urls": json.dumps([res_data["OriginalURL"]]),
|
||||
}
|
||||
check_data = {**base_data, **post_data}
|
||||
while res_data["Status"]["Code"] == "1":
|
||||
response = requests.post(url=url, data=check_data,)
|
||||
res_data = response.json()[0]
|
||||
|
||||
# Download image
|
||||
current_path = Path(self.original_file.path)
|
||||
temp_dir = Path(tempfile.mkdtemp())
|
||||
temp_path = temp_dir / (current_path.stem + "-resized" + current_path.suffix)
|
||||
output.save(temp_path)
|
||||
temp_path = temp_dir / (current_path.stem + "-processed" + current_path.suffix)
|
||||
img = requests.get(res_data["LossyURL"], stream=True)
|
||||
with open(temp_path, "wb") as temp_file:
|
||||
for chunk in img:
|
||||
temp_file.write(chunk)
|
||||
|
||||
# Link it to our model
|
||||
with open(temp_path, "rb") as output_file:
|
||||
f = File(output_file)
|
||||
self.processed_file.save(temp_path.name, f, save=False)
|
||||
|
||||
temp_path.unlink()
|
||||
temp_dir.rmdir()
|
||||
return super().save(*args, **kwargs)
|
||||
|
|
|
@ -70,6 +70,7 @@ INSTALLED_APPS = [
|
|||
"articles",
|
||||
"attachments",
|
||||
"anymail",
|
||||
"django_cleanup.apps.CleanupConfig",
|
||||
]
|
||||
|
||||
MIDDLEWARE = [
|
||||
|
@ -175,3 +176,5 @@ BLOG = {
|
|||
"description": "My take on tech-related subjects (but not only)",
|
||||
"base_url": os.getenv("BLOG_BASE_URL", "https://gabnotes.org/"),
|
||||
}
|
||||
|
||||
SHORTPIXEL_API_KEY = os.getenv("SHORTPIXEL_API_KEY")
|
||||
|
|
|
@ -4,3 +4,5 @@ gunicorn==20.0.4
|
|||
Pygments==2.6.1
|
||||
django-anymail[mailgun]==7.2.1
|
||||
pillow==7.2.0
|
||||
django-cleanup==5.0.0
|
||||
requests==2.24.0
|
||||
|
|
Reference in a new issue