1. 程式人生 > >使用PIL模組儲存影象時的報錯:cannot write mode P as JPEG

使用PIL模組儲存影象時的報錯:cannot write mode P as JPEG

一、背景

最近我需要自己訓練VGG模型,當然自己也採集了一部分資料。在VGG模型中,輸入資料是224*224尺寸的,因此需要對資料進行批量resize處理,這是背景。

二、出現問題的原因

首先給出我批量resize圖片的簡單程式碼:

import os
from PIL import Image

# 將所有影象resize成224*224,並儲存在目錄'result/'下
def resize_image(image_name):
    # 獲取輸入資料夾中的所有檔案
    files = os.listdir('./data/' + image_name)

    output_dir = './result/' + image_name
    # 判斷輸出資料夾是否存在,不存在則建立
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    for file in files:
        img = Image.open('./data/' + image_name + file)
        img = img.resize((224, 224), Image.ANTIALIAS)
        img.save(os.path.join(output_dir, file))


if __name__ == '__main__':
    resize_image('chengqiang/')

直接執行上述程式碼,然後就報錯了:

對於這個問題的原因,查了一下,因為我使用的是PIL模組,對於PIL模組來說,其模式包括以下幾種:

# 參考連結:https://www.jianshu.com/p/e8d058767dfa

模式
1             1位畫素,黑和白,存成8位的畫素
L             8位畫素,黑白
P             8位畫素,使用調色盤對映到任何其他模式
RGB           3×8位畫素,真彩
RGBA          4×8位畫素,真彩+透明通道
CMYK          4×8位畫素,顏色隔離
YCbCr         3×8位畫素,彩色視訊格式
I             32位整型畫素
F             32位浮點型畫素

報錯原因也很明顯,因為有圖片的模式是“P”,不是"RGB",所以無法直接寫入儲存,找到這張圖片,發現和普通的彩色圖片並沒有什麼區別:

具體檢視圖片模式的方法為:

    img = Image.open('./data/chengqiang/117.jpg')
    print(img.mode)

三、問題解決方法

對於這個問題,需要做的也很簡單,無非就是將模式“P”轉化為“RGB”模式,再儲存為“jpg”就可以了,所以只用增加兩行程式碼:

    if img.mode == "P":
        img = img.convert('RGB')

可以看到新增後程序就能夠順利執行:

最後附上完整程式碼:

import os
from PIL import Image

# 將所有影象resize成224*224,並儲存在目錄'result/'下
def resize_image(image_name):
    # 獲取輸入資料夾中的所有檔案
    files = os.listdir('./data/' + image_name)

    output_dir = './result/' + image_name
    # 判斷輸出資料夾是否存在,不存在則建立
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    for file in files:
        img = Image.open('./data/' + image_name + file)
        if img.mode == "P":
            img = img.convert('RGB')
        img = img.resize((224, 224), Image.ANTIALIAS)
        img.save(os.path.join(output_dir, file))


if __name__ == '__main__':
    resize_image('chengqiang/')