feat: Image optimization

This commit is contained in:
MitulDavid 2021-08-02 18:23:26 +05:30
parent 47ac923b3e
commit a3430ca2a9
5 changed files with 48 additions and 11 deletions

View file

@ -28,7 +28,7 @@ import frappe
from frappe import _, conf
from frappe.model.document import Document
from frappe.utils import call_hook_method, cint, cstr, encode, get_files_path, get_hook_method, random_string, strip
from frappe.utils.image import strip_exif_data
from frappe.utils.image import strip_exif_data, optimize_image
class MaxFileSizeReachedError(frappe.ValidationError):
pass
@ -876,6 +876,15 @@ def extract_images_from_html(doc, content):
data = match.group(1)
data = data.split("data:")[1]
headers, content = data.split(",")
mtype = headers.split(";")[0]
if isinstance(content, str):
content = content.encode("utf-8")
if b"," in content:
content = content.split(b",")[1]
content = base64.b64decode(content)
content = optimize_image(content, mtype)
if "filename=" in headers:
filename = headers.split("filename=")[-1]
@ -884,7 +893,6 @@ def extract_images_from_html(doc, content):
if not isinstance(filename, str):
filename = str(filename, 'utf-8')
else:
mtype = headers.split(";")[0]
filename = get_random_filename(content_type=mtype)
doctype = doc.parenttype if doc.parent else doc.doctype
@ -896,7 +904,7 @@ def extract_images_from_html(doc, content):
"attached_to_doctype": doctype,
"attached_to_name": name,
"content": content,
"decode": True
"decode": False
})
_file.save(ignore_permissions=True)
file_url = _file.file_url

View file

@ -10,6 +10,8 @@ from frappe.utils import cint
from frappe import _, is_whitelisted
from frappe.utils.response import build_response
from frappe.utils.csvutils import build_csv_response
from frappe.utils.image import optimize_image
from mimetypes import guess_type
from frappe.core.doctype.server_script.server_script_utils import run_server_script_api
@ -145,6 +147,7 @@ def upload_file():
folder = frappe.form_dict.folder or 'Home'
method = frappe.form_dict.method
filename = frappe.form_dict.file_name
optimize = frappe.form_dict.optimize
content = None
if 'file' in files:
@ -152,12 +155,15 @@ def upload_file():
content = file.stream.read()
filename = file.filename
content_type = guess_type(filename)[0]
if optimize and content_type.startswith("image/"):
content = optimize_image(content, content_type)
frappe.local.uploaded_file = content
frappe.local.uploaded_filename = filename
if not file_url and (frappe.session.user == "Guest" or (user and not user.has_desk_access())):
import mimetypes
filetype = mimetypes.guess_type(filename)[0]
filetype = guess_type(filename)[0]
if filetype not in ALLOWED_MIMETYPES:
frappe.throw(_("You can only upload JPG, PNG, PDF, or Microsoft documents."))

View file

@ -478,6 +478,10 @@ export default {
form_data.append('method', this.method);
}
if (this.attach_doc_image) {
form_data.append('optimize', true);
}
xhr.send(form_data);
});
},

View file

@ -11,7 +11,7 @@ from frappe import _
from frappe import conf
from copy import copy
from urllib.parse import unquote
from frappe.utils.image import optimize_image
class MaxFileSizeReachedError(frappe.ValidationError):
pass
@ -386,6 +386,15 @@ def extract_images_from_html(doc, content):
data = match.group(1)
data = data.split("data:")[1]
headers, content = data.split(",")
mtype = headers.split(";")[0]
if isinstance(content, str):
content = content.encode("utf-8")
if b"," in content:
content = content.split(b",")[1]
content = base64.b64decode(content)
content = optimize_image(content, mtype)
if "filename=" in headers:
filename = headers.split("filename=")[-1]
@ -394,7 +403,6 @@ def extract_images_from_html(doc, content):
if not isinstance(filename, str):
filename = str(filename, 'utf-8')
else:
mtype = headers.split(";")[0]
filename = get_random_filename(content_type=mtype)
doctype = doc.parenttype if doc.parent else doc.doctype
@ -405,7 +413,7 @@ def extract_images_from_html(doc, content):
name = doc.reference_name
# TODO fix this
file_url = save_file(filename, content, doctype, name, decode=True).get("file_url")
file_url = save_file(filename, content, doctype, name, decode=False).get("file_url")
if not frappe.flags.has_dataurl:
frappe.flags.has_dataurl = True

View file

@ -1,6 +1,8 @@
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors
# MIT License. See license.txt
import os
from PIL import Image
import io
def resize_images(path, maxdim=700):
from PIL import Image
@ -26,9 +28,6 @@ def strip_exif_data(content, content_type):
Bytes: Stripped image content
"""
from PIL import Image
import io
original_image = Image.open(io.BytesIO(content))
output = io.BytesIO()
@ -38,4 +37,16 @@ def strip_exif_data(content, content_type):
content = output.getvalue()
return content
def optimize_image(content, content_type, max_width=1920, max_height=1080, optimize=True, quality=85):
image = Image.open(io.BytesIO(content))
image_format = content_type.split('/')[1]
size = max_width, max_height
image.thumbnail(size, Image.LANCZOS)
output = io.BytesIO()
image.save(output, format=image_format, optimize=optimize, quality=quality, save_all=True if image_format=='gif' else None)
content = output.getvalue()
return content