Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Python中调整图像大小需要专家建议,因为现有解决方案有例外_Python_Image_Python Imaging Library_Pillow - Fatal编程技术网

在Python中调整图像大小需要专家建议,因为现有解决方案有例外

在Python中调整图像大小需要专家建议,因为现有解决方案有例外,python,image,python-imaging-library,pillow,Python,Image,Python Imaging Library,Pillow,现在有3种调整图像大小的解决方案: 第一: 第二: 第三条: img = Image.open('C:\\Users\\Vishal\\Desktop\\Test\\xyx.jpg') img = img.convert('RGB') img = img.resize((90, 90), Image.ANTIALIAS) img.save('C:\\Users\\Vishal\\Desktop\\Test\\xyz.jpg') 在

现在有3种调整图像大小的解决方案: 第一:

第二:

第三条:

        img = Image.open('C:\\Users\\Vishal\\Desktop\\Test\\xyx.jpg')
        img = img.convert('RGB')
        img = img.resize((90, 90), Image.ANTIALIAS)
        img.save('C:\\Users\\Vishal\\Desktop\\Test\\xyz.jpg')
在某些情况下,1st的问题表现为错误“无法将模式RGBA写入JPEG”, 第二种是“不好的透明度遮罩”,第三种的问题是它在所有情况下都能工作,但调整大小后具有透明度的图像的背景为黑色,这是不可接受的,而且在边缘附近可以看到扭曲的颜色像素。 那么,这些问题的普遍解决方案是什么呢

注:(所需的输出格式为.jpg,要调整大小的图像在刮取时的格式有所不同,主要是透明背景的.png)

更新: 根据评论,我根据alpha条件放置了一个if else,如下所示:

img = Image.open('C:\\Users\\Vishal\\Desktop\\Test\\xyx.jpg")
has_alpha = img.mode == 'RGBA'
print(has_alpha)
if has_alpha == True:
    bg = Image.new("RGB", img.size, (255, 255, 255))
    bg.paste(img, img)
    bg = bg.resize((80, 80), Image.ANTIALIAS)
    bg.save('C:\\Users\\Vishal\\Desktop\\Test\\xyz.jpg", quality=92)
else:
    img.resize((80, 80), Image.ANTIALIAS)
    img.save('C:\\Users\\Vishal\\Desktop\\Test\\xyz.jpg", quality=92)
它工作正常,但在一些罕见的情况下,如果α为假,我会得到以下错误

False
Traceback (most recent call last):
  File "C:\Intel\lib\site-packages\PIL\JpegImagePlugin.py", line 620, in _save
    rawmode = RAWMODE[im.mode]
KeyError: 'P'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "resize.py", line 33, in <module>
    img.save('C:\\Users\\Vishal\\Desktop\\Test\\xyz.jpg", quality=92)
  File "C:\Intel\lib\site-packages\PIL\Image.py", line 1935, in save
    save_handler(self, fp, filename)
  File "C:\Intel\lib\site-packages\PIL\JpegImagePlugin.py", line 622, in _save
    raise IOError("cannot write mode %s as JPEG" % im.mode)
OSError: cannot write mode P as JPEG
False
回溯(最近一次呼叫最后一次):
文件“C:\Intel\lib\site packages\PIL\JpegImagePlugin.py”,第620行,保存
rawmode=rawmode[im.mode]
KeyError:'P'
在处理上述异常期间,发生了另一个异常:
回溯(最近一次呼叫最后一次):
文件“resize.py”,第33行,在
img.save('C:\\Users\\Vishal\\Desktop\\Test\\xyz.jpg',quality=92)
文件“C:\Intel\lib\site packages\PIL\Image.py”,第1935行,保存
保存\u处理程序(self、fp、filename)
文件“C:\Intel\lib\site packages\PIL\JpegImagePlugin.py”,第622行,保存
raise IOError(“无法将模式%s写入JPEG”%im.mode)
OSError:无法将模式P写入JPEG

正如PIL错误消息所指出的,JPEG不支持透明度。要处理使用透明度的图像,您需要将它们粘贴到RGB背景图像上。这就是您的第二个选项所做的:
image.new(“RGB”,img.size,(255,255,255))
创建一个与
img
大小相同的新图像,所有像素设置为
(255、255、255)
,为白色。(您也可以使用字符串指定PIL的颜色)

因此,要正确执行此调整大小和转换任务,您需要确定图像是否具有透明度。您可以通过检查
image.mode
字符串来实现这一点,则图像具有透明度。这里有一个简短的演示,它使用一个中等浅灰色作为背景。我使用模块从输入文件名创建JPEG文件名。此模块在Python 3.4+中提供

更新 此代码的原始版本不处理调色板映射图像,但此新版本处理,包括具有透明度的调色板映射图像

def resize_to_jpg(fname, newsize, background):
    img = Image.open(fname)
    #img.show()

    print('Resizing', fname, 'Mode =', img.mode) 
 
    if img.mode == "P":
        # Handle palette-mapped images
        if 'transparency' in img.info:
            img = img.convert('RGBA')
        else:
            img = img.convert('RGB')

    if img.mode == "RGBA":
        # The image has transparency
        out = Image.new("RGB", img.size, background)
        # Use the image's own alpha channel as the mask
        out.paste(img, mask=img)
    else:
        out = img
    out = out.resize(newsize, Image.ANTIALIAS)
    #out.show()

    # Construct output file name
    outname = str(PurePath(fname).with_suffix('.jpg'))
    out.save(outname, quality=90, optimize=True)
    print(outname, 'saved')

newsize = (120, 120)
background = (192, 192, 192)

files = (
    'RhombicPlain.png', 
    'RhombicAlpha.png', 
)
for fname in files:
    resize_to_jpg(fname, newsize, background)       
输出

Resizing RhombicPlain.png Mode = RGB
RhombicPlain.jpg saved
Resizing RhombicAlpha.png Mode = RGBA
RhombicAlpha.jpg saved
以下是我使用POV光线创建的输入图像RhombicPlain.png和RhombicAlpha.png

以下是输出图像RhombicPlain.jpg和RhombicAlpha.jpg


怎样才能有一个通用的解决方案?如果您将具有透明度的图像转换为不具有透明度的形式,那么您将丢弃信息,并且必须进行一些更改。如果默认黑色背景不可接受,则需要选择其他背景。白色和灰色的格子背景可以接受吗?我还没有尝试过不同的背景,我需要做些什么来改变呢?请提出建议。已应用解决方案,但仍存在一些例外情况。将等待…谢谢您的时间。此代码出现相同错误:
Mode=P回溯(最近一次调用):文件“C:\Intel\lib\site packages\PIL\JpegImagePlugin.py”,第620行,在_saverawmode=rawmode[im.Mode]中KeyError:“P”在处理上述异常期间,发生了另一个异常:回溯(上次调用):文件“resize.py”,第62行,在resize_to_jpg(fname,newsize,background)文件“resize.py”,第53行,在resize_to_jpg out.save(outname,quality=90,optimize=True)中OSError:无法写入模式P,因为JPEG
工作正常。。。。再次感谢。。我认为这就是普遍性。
def resize_to_jpg(fname, newsize, background):
    img = Image.open(fname)
    #img.show()

    print('Resizing', fname, 'Mode =', img.mode) 
 
    if img.mode == "P":
        # Handle palette-mapped images
        if 'transparency' in img.info:
            img = img.convert('RGBA')
        else:
            img = img.convert('RGB')

    if img.mode == "RGBA":
        # The image has transparency
        out = Image.new("RGB", img.size, background)
        # Use the image's own alpha channel as the mask
        out.paste(img, mask=img)
    else:
        out = img
    out = out.resize(newsize, Image.ANTIALIAS)
    #out.show()

    # Construct output file name
    outname = str(PurePath(fname).with_suffix('.jpg'))
    out.save(outname, quality=90, optimize=True)
    print(outname, 'saved')

newsize = (120, 120)
background = (192, 192, 192)

files = (
    'RhombicPlain.png', 
    'RhombicAlpha.png', 
)
for fname in files:
    resize_to_jpg(fname, newsize, background)       
Resizing RhombicPlain.png Mode = RGB
RhombicPlain.jpg saved
Resizing RhombicAlpha.png Mode = RGBA
RhombicAlpha.jpg saved