Image Conversion - Cannot write mode RGBA as JPEG

后端 未结 2 431
无人及你
无人及你 2020-12-11 12:16

I\'m trying to resize & reduce quality of image before upload in project. Here\'s what I tried,

def save(self):
    im = Image.open(self.image)
    outpu         


        
相关标签:
2条回答
  • 2020-12-11 12:57

    Summary timop and 2:

    • backgroud

      • JPG not support alpha = transparency
      • RGBA, P has alpha = 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 to RGB
      • then save to JPG
    • your code

      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)
      
    • More for you:

    about resize & reduce quality of image, I have implement a function, for you (and others) to refer:

    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
    

    latest code can found here:

    https://github.com/crifan/crifanLibPython/blob/master/crifanLib/crifanMultimedia.py

    0 讨论(0)
  • 2020-12-11 13:00

    If your image.mode is "P" or "RGBA" and you want to convert it to jpeg then you need to first convert the image.mode because the previous modes aren't supported for jpeg

    if im.mode in ("RGBA", "P"):
        im = im.convert("RGB")
    

    https://github.com/python-pillow/Pillow/issues/2609

    0 讨论(0)
提交回复
热议问题