首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在JPG图像上操作时获取“不能将模式P写为JPEG”

在JPG图像上操作时获取“不能将模式P写为JPEG”
EN

Stack Overflow用户
提问于 2014-02-10 05:22:52
回答 5查看 67.7K关注 0票数 90

我试图调整一些图像的大小,其中大部分是JPG。但在一些图片中,我得到了一个错误:

代码语言:javascript
运行
复制
Traceback (most recent call last):
  File "image_operation_new.py", line 168, in modifyImage
    tempImage.save(finalName);
  File "/Users/kshitiz/.virtualenvs/django_project/lib/python2.7/site-     packages/PIL/Image.py", line 1465, in save
   save_handler(self, fp, filename)
  File "/Users/kshitiz/.virtualenvs/django_project/lib/python2.7/site-   packages/PIL/JpegImagePlugin.py", line 455, in _save
    raise IOError("cannot write mode %s as JPEG" % im.mode)
IOError: cannot write mode P as JPEG

我没有改变形象类型,我使用的是枕头库。我的操作系统是Mac。我如何解决这个问题?

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2014-02-10 05:37:35

您需要将图像转换为RGB模式。

代码语言:javascript
运行
复制
Image.open('old.jpeg').convert('RGB').save('new.jpeg')
票数 170
EN

Stack Overflow用户

发布于 2019-12-25 09:24:11

但是,这个答案已经很老了,但是,我认为在进行转换之前,通过检查模式,我会找到一种更好的方法来做到这一点:

代码语言:javascript
运行
复制
if img.mode != 'RGB':
    img = img.convert('RGB')

这是保存JPEG格式的图像所必需的。

票数 25
EN

Stack Overflow用户

发布于 2020-12-08 01:43:43

12综述

  • 背景
    • JPG不支持alpha = transparency
    • RGBAPalpha = transparency
      • RGBA= Red Green Blue Alpha

  • 结果
    • cannot write mode RGBA as JPEG
    • cannot write mode P as JPEG

  • 溶液
    • 在保存到JPG之前,丢弃alpha = transparency
      • 例如:将Image转换为RGB

代码语言:javascript
运行
复制
- then save to `JPG`
  • 你的代码

代码语言:javascript
运行
复制
if im.mode == "JPEG":
    im.save("xxx.jpg")
    # in most case, resulting jpg file is resized small one
elif 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
  • 为你做更多:

关于调整imgae文件的大小,我实现了一个函数,供您参考:

代码语言:javascript
运行
复制
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/python3/crifanLib/thirdParty/crifanPillow.py

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21669657

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档