Getting "cannot write mode P as JPEG" while operating on JPG image
You need to convert the image to RGB mode.
Image.open('old.jpeg').convert('RGB').save('new.jpeg')
This answer is quite old, however, I thought I will put a better way to do the same by checking for the mode before doing the conversion:
if img.mode != 'RGB': img = img.convert('RGB')
This is required to save your image in JPEG format.
- backgroud
JPG
not supportalpha = transparency
RGBA
,P
hasalpha = transparency
RGBA
=Red Green Blue Alpha
- result
cannot write mode RGBA as JPEG
cannot write mode P as JPEG
- solution
- before save to JPG, discard
alpha = transparency
- such as: convert
Image
toRGB
- such as: convert
- then save to
JPG
- before save to JPG, discard
- your code
if im.mode == "JPEG": im.save("xxx.jpg") # in most case, resulting jpg file is resized small oneelif rgba_or_p_im.mode in ["RGBA", "P"]: rgb_im = rgba_or_p_im.convert("RGB") rgb_im.save("xxx.jpg") # some minor case, resulting jpg file is larger one, should meet your expectation
- do more for you:
about resize imgae file, I have implement a function, for your refer:
from PIL import Image, ImageDrawcfgDefaultImageResample = Image.BICUBIC # Image.LANCZOSdef 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
latest code can found here:
https://github.com/crifan/crifanLibPython/blob/master/python3/crifanLib/thirdParty/crifanPillow.py