取消图片压缩功能
This commit is contained in:
parent
a44c7c2bae
commit
a90ed5c4ea
@ -14,7 +14,6 @@ from oss2.models import PutObjectResult
|
|||||||
from core.exception import CustomException
|
from core.exception import CustomException
|
||||||
from core.logger import logger
|
from core.logger import logger
|
||||||
from utils import status
|
from utils import status
|
||||||
from utils.file.compress.cpressJPG import compress_jpg_png
|
|
||||||
from utils.file.file_manage import FileManage
|
from utils.file.file_manage import FileManage
|
||||||
from utils.file.file_base import FileBase
|
from utils.file.file_base import FileBase
|
||||||
|
|
||||||
@ -47,13 +46,12 @@ class AliyunOSS(FileBase):
|
|||||||
self.bucket = oss2.Bucket(auth, bucket.endpoint, bucket.bucket)
|
self.bucket = oss2.Bucket(auth, bucket.endpoint, bucket.bucket)
|
||||||
self.baseUrl = bucket.baseUrl
|
self.baseUrl = bucket.baseUrl
|
||||||
|
|
||||||
async def upload_image(self, path: str, file: UploadFile, compress: bool = False, max_size: int = 10) -> str:
|
async def upload_image(self, path: str, file: UploadFile, max_size: int = 10) -> str:
|
||||||
"""
|
"""
|
||||||
上传图片
|
上传图片
|
||||||
|
|
||||||
:param path: path由包含文件后缀,不包含Bucket名称组成的Object完整路径,例如abc/efg/123.jpg。
|
:param path: path由包含文件后缀,不包含Bucket名称组成的Object完整路径,例如abc/efg/123.jpg。
|
||||||
:param file: 文件对象
|
:param file: 文件对象
|
||||||
:param compress: 是否压缩该文件
|
|
||||||
:param max_size: 图片文件最大值,单位 MB,默认 10MB
|
:param max_size: 图片文件最大值,单位 MB,默认 10MB
|
||||||
:return: 上传后的文件oss链接
|
:return: 上传后的文件oss链接
|
||||||
"""
|
"""
|
||||||
@ -61,14 +59,7 @@ class AliyunOSS(FileBase):
|
|||||||
await self.validate_file(file, max_size, self.IMAGE_ACCEPT)
|
await self.validate_file(file, max_size, self.IMAGE_ACCEPT)
|
||||||
# 生成文件路径
|
# 生成文件路径
|
||||||
path = self.generate_static_file_path(path, file.filename)
|
path = self.generate_static_file_path(path, file.filename)
|
||||||
if compress:
|
file_data = await file.read()
|
||||||
# 压缩图片
|
|
||||||
file_path = await FileManage.async_save_temp_file(file)
|
|
||||||
new_file = compress_jpg_png(file_path, originpath=os.path.abspath(file_path))
|
|
||||||
with open(new_file, "rb") as f:
|
|
||||||
file_data = f.read()
|
|
||||||
else:
|
|
||||||
file_data = await file.read()
|
|
||||||
return await self.__upload_file_to_oss(path, file_data)
|
return await self.__upload_file_to_oss(path, file_data)
|
||||||
|
|
||||||
async def upload_video(self, path: str, file: UploadFile, max_size: int = 100) -> str:
|
async def upload_video(self, path: str, file: UploadFile, max_size: int = 100) -> str:
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
from PIL import Image, ExifTags # 安装依赖包:pip3 install pillow
|
|
||||||
from utils.file.compress import dynamic_quality
|
|
||||||
import os
|
|
||||||
import time
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
|
||||||
PIL读取的图像发生自动旋转:https://blog.csdn.net/mizhenpeng/article/details/82794112
|
|
||||||
使用python批量压缩图片文件:https://blog.csdn.net/weixin_41855010/article/details/120723943
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def compress_jpg_png(filename, originpath):
|
|
||||||
name = filename.rstrip('.png').rstrip('.jpg')
|
|
||||||
im = Image.open(os.path.join(originpath, filename))
|
|
||||||
# 解决图像方向问题
|
|
||||||
try:
|
|
||||||
for orientation in ExifTags.TAGS.keys():
|
|
||||||
if ExifTags.TAGS[orientation] == 'Orientation': break
|
|
||||||
exif = dict(im._getexif().items())
|
|
||||||
if exif[orientation] == 3:
|
|
||||||
im = im.rotate(180, expand=True)
|
|
||||||
elif exif[orientation] == 6:
|
|
||||||
im = im.rotate(270, expand=True)
|
|
||||||
elif exif[orientation] == 8:
|
|
||||||
im = im.rotate(90, expand=True)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
# print(im.format,im.size,im.mode)
|
|
||||||
im = im.convert('RGB')
|
|
||||||
im.format = "JPEG"
|
|
||||||
new_photo = im.copy()
|
|
||||||
new_photo.thumbnail(im.size, resample=Image.ANTIALIAS)
|
|
||||||
save_args = {'format': im.format}
|
|
||||||
# print(save_args)
|
|
||||||
# if im.format=='JPEG':
|
|
||||||
# save_args['quality']=20
|
|
||||||
save_args['quality'], value = dynamic_quality.jpeg_dynamic_quality(im)
|
|
||||||
save_args['optimize'] = True
|
|
||||||
save_args['progressive=True'] = True
|
|
||||||
# print("JPEG Quality Changed")
|
|
||||||
# elif im.format=='PNG':
|
|
||||||
# save_args['format']='JPEG'
|
|
||||||
# save_args['quality']=5
|
|
||||||
# print("PNG Quality Changed")
|
|
||||||
new_file = os.path.join(originpath, name + str(int(time.time())) + ".jpg")
|
|
||||||
new_photo.save(new_file, **save_args)
|
|
||||||
return new_file
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
print(compress_jpg_png("1.jpg", "E:\\test"))
|
|
@ -1,66 +0,0 @@
|
|||||||
import PIL.Image # 安装依赖包:pip3 install pillow
|
|
||||||
from math import log
|
|
||||||
from SSIM_PIL import compare_ssim # 安装依赖包:pip3 install SSIM-PIL
|
|
||||||
|
|
||||||
|
|
||||||
def get_ssim_at_quality(photo, quality):
|
|
||||||
"""Return the ssim for this JPEG image saved at the specified quality"""
|
|
||||||
ssim_photo = "tmp.jpg"
|
|
||||||
# optimize is omitted here as it doesn't affect
|
|
||||||
# quality but requires additional memory and cpu
|
|
||||||
photo.save(ssim_photo, format="JPEG", quality=quality, progressive=True)
|
|
||||||
ssim_score = compare_ssim(photo, PIL.Image.open(ssim_photo))
|
|
||||||
return ssim_score
|
|
||||||
|
|
||||||
|
|
||||||
def _ssim_iteration_count(lo, hi):
|
|
||||||
"""Return the depth of the binary search tree for this range"""
|
|
||||||
if lo >= hi:
|
|
||||||
return 0
|
|
||||||
else:
|
|
||||||
return int(log(hi - lo, 2)) + 1
|
|
||||||
|
|
||||||
|
|
||||||
def jpeg_dynamic_quality(original_photo):
|
|
||||||
"""Return an integer representing the quality that this JPEG image should be
|
|
||||||
saved at to attain the quality threshold specified for this photo class.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
original_photo - a prepared PIL JPEG image (only JPEG is supported)
|
|
||||||
"""
|
|
||||||
ssim_goal = 0.9 #the original value is 0.95
|
|
||||||
hi = 35 #the original value is 85
|
|
||||||
lo = 30 #the original value is 80
|
|
||||||
|
|
||||||
# working on a smaller size image doesn't give worse results but is faster
|
|
||||||
# changing this value requires updating the calculated thresholds
|
|
||||||
photo = original_photo.resize((200, 200))
|
|
||||||
|
|
||||||
# if not _should_use_dynamic_quality():
|
|
||||||
# default_ssim = get_ssim_at_quality(photo, hi)
|
|
||||||
# return hi, default_ssim
|
|
||||||
|
|
||||||
# 95 is the highest useful value for JPEG. Higher values cause different behavior
|
|
||||||
# Used to establish the image's intrinsic ssim without encoder artifacts
|
|
||||||
normalized_ssim = get_ssim_at_quality(photo, 10)
|
|
||||||
selected_quality = selected_ssim = None
|
|
||||||
|
|
||||||
# loop bisection. ssim function increases monotonically so this will converge
|
|
||||||
for i in range(_ssim_iteration_count(lo, hi)):
|
|
||||||
curr_quality = (lo + hi) // 2
|
|
||||||
curr_ssim = get_ssim_at_quality(photo, curr_quality)
|
|
||||||
ssim_ratio = curr_ssim / normalized_ssim
|
|
||||||
|
|
||||||
if ssim_ratio >= ssim_goal:
|
|
||||||
# continue to check whether a lower quality level also exceeds the goal
|
|
||||||
selected_quality = curr_quality
|
|
||||||
selected_ssim = curr_ssim
|
|
||||||
hi = curr_quality
|
|
||||||
else:
|
|
||||||
lo = curr_quality
|
|
||||||
|
|
||||||
if selected_quality:
|
|
||||||
return selected_quality, selected_ssim
|
|
||||||
else:
|
|
||||||
default_ssim = get_ssim_at_quality(photo, hi)
|
|
||||||
return hi, default_ssim
|
|
@ -9,7 +9,6 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import os
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
from fastapi import UploadFile
|
from fastapi import UploadFile
|
||||||
from application.settings import TEMP_DIR
|
from application.settings import TEMP_DIR
|
||||||
|
@ -8,12 +8,10 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import io
|
import io
|
||||||
import os
|
import os
|
||||||
import shutil
|
|
||||||
import zipfile
|
import zipfile
|
||||||
from application.settings import STATIC_ROOT, BASE_DIR, STATIC_URL
|
from application.settings import STATIC_ROOT, BASE_DIR, STATIC_URL
|
||||||
from fastapi import UploadFile
|
from fastapi import UploadFile
|
||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
|
||||||
from core.exception import CustomException
|
from core.exception import CustomException
|
||||||
from utils.file.file_base import FileBase
|
from utils.file.file_base import FileBase
|
||||||
from aiopathlib import AsyncPath
|
from aiopathlib import AsyncPath
|
||||||
|
Loading…
x
Reference in New Issue
Block a user