我正在尝试调整大小在项目上传之前降低图像质量。这是我试过的,
def save(self):
im = Image.open(self.image)
output = BytesIO()
im = im.resize(240, 240)
im.save(output, format='JPEG', quality=95)
output.seek(0)
self.image = InMemoryUploadedFile(output, 'ImageField', "%s.jpg" % self.image.name.split('.')[0], 'image/jpeg', sys.getsizeof(output), None)
super(Model, self).save()
如果我上传了jpg
图片,但是如果我上传了png
或任何其他图片类型,那么它工作得很好,但它不起作用会引发cannot write mode RGBA as JPEG
& cannot write mode P as JPEG
等。
我们如何解决这个问题?谢谢!
答案 0 :(得分:0)
如果你的image.mode是" P"或" RGBA"并且您想将其转换为jpeg然后您需要先转换image.mode
,因为jpeg不支持以前的模式
if im.mode in ("RGBA", "P"):
im = im.convert("RGB")
答案 1 :(得分:0)
摘要timop
和2:
背景
JPG
不支持alpha = transparency
RGBA
,P
有alpha = transparency
RGBA
= Red Green Blue Alpha
结果
cannot write mode RGBA as JPEG
cannot write mode P as JPEG
解决方案
alpha = transparency
Image
转换为RGB
JPG
您的代码
if im.mode == "JPEG":
im.save(output, format='JPEG', quality=95)
elif im.mode in ["RGBA", "P"]:
im = im.convert("RGB")
im.save(output, format='JPEG', quality=95)
为您提供的更多信息:
关于resize & reduce quality of image
,我已经实现了一个功能,供您(和其他人)参考:
from PIL import Image, ImageDraw
cfgDefaultImageResample = Image.BICUBIC # Image.LANCZOS
def resizeImage(inputImage,
newSize,
resample=cfgDefaultImageResample,
outputFormat=None,
outputImageFile=None
):
"""
resize input image
resize normally means become smaller, reduce size
:param inputImage: image file object(fp) / filename / binary bytes
:param newSize: (width, height)
:param resample: PIL.Image.NEAREST, PIL.Image.BILINEAR, PIL.Image.BICUBIC, or PIL.Image.LANCZOS
https://pillow.readthedocs.io/en/stable/reference/Image.html#PIL.Image.Image.thumbnail
:param outputFormat: PNG/JPEG/BMP/GIF/TIFF/WebP/..., more refer:
https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html
if input image is filename with suffix, can omit this -> will infer from filename suffix
:param outputImageFile: output image file filename
:return:
input image file filename: output resized image to outputImageFile
input image binary bytes: resized image binary bytes
"""
openableImage = None
if isinstance(inputImage, str):
openableImage = inputImage
elif CommonUtils.isFileObject(inputImage):
openableImage = inputImage
elif isinstance(inputImage, bytes):
inputImageLen = len(inputImage)
openableImage = io.BytesIO(inputImage)
if openableImage:
imageFile = Image.open(openableImage)
elif isinstance(inputImage, Image.Image):
imageFile = inputImage
# <PIL.PngImagePlugin.PngImageFile image mode=RGBA size=3543x3543 at 0x1065F7A20>
imageFile.thumbnail(newSize, resample)
if outputImageFile:
# save to file
imageFile.save(outputImageFile)
imageFile.close()
else:
# save and return binary byte
imageOutput = io.BytesIO()
# imageFile.save(imageOutput)
outputImageFormat = None
if outputFormat:
outputImageFormat = outputFormat
elif imageFile.format:
outputImageFormat = imageFile.format
imageFile.save(imageOutput, outputImageFormat)
imageFile.close()
compressedImageBytes = imageOutput.getvalue()
compressedImageLen = len(compressedImageBytes)
compressRatio = float(compressedImageLen)/float(inputImageLen)
print("%s -> %s, resize ratio: %d%%" % (inputImageLen, compressedImageLen, int(compressRatio * 100)))
return compressedImageBytes
最新代码可在此处找到:
https://github.com/crifan/crifanLibPython/blob/master/crifanLib/crifanMultimedia.py