使用Python打開webp等格式圖片

問題

今天處理圖片的時候發現有一張後綴爲.jpg的圖片在電腦上無法打開,但是使用Chrome瀏覽器能打開。嘗試用OpenCV讀取,但是也無法打開。

仔細查看了OpenCV支持的圖片格式

Windows bitmaps - *.bmp, *.dib (always supported)
JPEG files - *.jpeg, *.jpg, *.jpe (see the Notes section)
JPEG 2000 files - *.jp2 (see the Notes section)
Portable Network Graphics - *.png (see the Notes section)
Portable image format - *.pbm, *.pgm, *.ppm (always supported)
Sun rasters - *.sr, *.ras (always supported)
TIFF files - *.tiff, *.tif (see the Notes section)

按照後綴判斷是jpg格式,仔細想想有可能是圖片後綴和實際格式不符合。通過以字節碼的形式讀取該圖片,發現一個問題:
在這裏插入圖片描述

思考

字節碼頭顯示RIFF和WEBPVP8這兩個關鍵信息,根據這判斷其不是jpg格式,再搜索發現這是谷歌推出的webp圖片格式。
以下是常見的圖片格式及判斷方法:

格式 描述 判斷方式
jpeg 用JFIF或者Exif格式保存的JPEG圖片 第7到第10個字節是b’JFIF’或者b’Exif’
png 可移植網絡圖形格式(Portable Network Graphic Format) 以字節串b’\x89PNG\r\n\x1a\n’開頭
gif GIF(Graphics Interchange Format)的87版本和89版本 前6個字節爲b’GIF87a’或者b’GIF89a’
tiff TIFF(Tag Image File Format)的兩種字節順序 前兩個字節爲b’MM’或者b’II’
rgb SGI ImgLib 以字節串b’\x01\xda’開頭
pbm Portable Bitmap 第1個字節爲b’P’,第2個字節爲b’1’或b’4’,第3個字節爲b’\t’或b’\n’或b’\r’
pgm Portable Graymap Files 第1個字節爲b’P’,第2個字節爲b’2’或b’5’,第3個字節爲b’\t’或b’\n’或b’\r’
ppm Portable Pixmap Files 第1個字節爲b’P’,第2個字節爲b’3’或b’6’,第3個字節爲b’\t’或b’\n’或b’\r’
rast Sun Raster 以字節串b’\x59\xA6\x6A\x95’開頭
xbm X Bitmap Files 以字節串b’#define ‘開頭
bmp Bitmap,Windows標準圖像文件格式 以字節串b’BM’開頭
webp 谷歌的WebP格式,Python3.5加入 以字節串b’RIFF’開頭並且第9到第12個字節爲b’WEBP’
exr OpenEXR,Python3.5加入 以字節串b’\x76\x2f\x31\x01’開頭

解決

既然知道了這個假的“jpg”實際上是“webp”圖片。那麼如何讀取呢?
使用OpenCV讀取會報錯,使用PIL發現可以讀取。
在這裏插入圖片描述

from PIL import Image
import matplotlib.pyplot as plt
img=Image.open('fake.jpg')
plt.imshow(img)
plt.show()

在這裏插入圖片描述
可以直接通過PIL讀取後存儲爲真正的jpg格式圖片。

from PIL import Image
img = Image.open('fake.jpg')
img.save('real.jpg')

擴展

圖片格式繁多,在處理時很容易出現格式問題。怎麼樣才能確保出現報錯前就能預知問題呢?
經過搜索,發現了一個比較好用的package——imghdr
在這裏插入圖片描述
這個包是python自帶,使用方式如下:

import imghdr
imghdr.what('fake.jpg')

在這裏插入圖片描述
處理圖片前判斷一下格式,就能避免很多格式上的問題。
另外,python下有webp包可以加載和保存webp格式圖片。

pip install webp
import webp

# Save an image
webp.save_image(img, 'image.webp', quality=80)

# Load an image
img = webp.load_image('image.webp', 'RGBA')

# Save an animation
webp.save_images(imgs, 'anim.webp', fps=10, lossless=True)

# Load an animation
imgs = webp.load_images('anim.webp', 'RGB', fps=10)

參考資料

[1] RIFF格式圖片在ios瀏覽器中無法顯示
[2] OpenCV的imread函數支持的圖片格式
[3] imghdr — 推測圖像類型
[4] python webp package

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章