我希望对本地的图片进行压缩,用python实现此功能
steo1:C:\Users\wangrusheng\PycharmProjects\FastAPIProject1\hello.py 其中,生成的图片,在py同路径下
from PIL import Image
from enum import Enum
import io
class ImageCompressionQuality(Enum):
LOW = 0.3
MEDIUM = 0.5
HIGH = 0.7
@staticmethod
def custom(value):
return max(0.0, min(1.0, value))
class ImageCompression:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def _convert_image_mode(self, image):
Convert image to RGB mode if needed
img = image.copy()
if img.mode in ('RGBA', 'LA', 'P'):
img = img.convert('RGB')
return img
def compress_image(self, image, quality=0.5):
Compress image with specified quality (0.0-1.0 or ImageCompressionQuality enum)
try:
# Handle quality parameter
if isinstance(quality, ImageCompressionQuality):
quality_value = quality.value
else:
quality_value = max(0.0, min(1.0, float(quality)))
img = self._convert_image_mode(image)
quality_percent = int(quality_value * 100)
# Save to bytes buffer
img_io = io.BytesIO()
img.save(img_io, format='JPEG', quality=quality_percent, optimize=True)
img_io.seek(0)
return img_io.getvalue()
except Exception as e:
print(fCompression error: {e})
return None
def compress_to_target_size(self, image, target_size_kb):
Compress image to target size in KB using binary search
target_size_bytes = target_size_kb * 1024
min_quality = 0.0
max_quality = 1.0
quality = 0.8
best_data = None
# Initial check
current_data = self.compress_image(image, quality)
if current_data and len(current_data) <= target_size_bytes:
return current_data
# Binary search
for _ in range(6):
quality = (min_quality + max_quality) / 2
current_data = self.compress_image(image, quality)
if not current_data:
break
if len(current_data) > target_size_bytes:
max_quality = quality
else:
min_quality = quality
best_data = current_data
return best_data or self.compress_image(image, min_quality)
def resize_image(self, image, max_dimension):
Resize image to maximum dimension while maintaining aspect ratio
img = image.copy()
img.thumbnail((max_dimension, max_dimension))
return img
def optimize_for_upload(self, image):
Optimize image for upload (resize + compress to 500KB)
resized_img = self.resize_image(image, 1200)
return self.compress_to_target_size(resized_img, 500)
# 使用示例
if __name__ == __main__:
img_path = rC:\Users\wangrusheng\Downloads\apple.jpg
try:
# 加载图片
with Image.open(img_path) as img:
# 创建压缩器实例
compressor = ImageCompression()
# 示例1: 使用中等质量压缩
compressed_data = compressor.compress_image(img, ImageCompressionQuality.MEDIUM)
with open(compressed_medium.jpg, wb) as f:
f.write(compressed_data)
# 示例2: 压缩到300KB
target_data = compressor.compress_to_target_size(img, 300)
if target_data:
with open(compressed_300kb.jpg, wb) as f:
f.write(target_data)
# 示例3: 调整尺寸并优化上传
optimized_data = compressor.optimize_for_upload(img)
if optimized_data:
with open(optimized_upload.jpg, wb) as f:
f.write(optimized_data)
except Exception as e:
print(fError processing image: {e})
end