feat: Image optimization
This commit is contained in:
parent
47ac923b3e
commit
a3430ca2a9
5 changed files with 48 additions and 11 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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."))
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
},
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Add table
Reference in a new issue