今天处理图片的时候发现有一张后缀为.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’开头gifGIF(Graphics Interchange Format)的87版本和89版本前6个字节为b’GIF87a’或者b’GIF89a’tiffTIFF(Tag Image File Format)的两种字节顺序前两个字节为b’MM’或者b’II’rgbSGI ImgLib以字节串b’\x01\xda’开头pbmPortable Bitmap第1个字节为b’P’,第2个字节为b’1’或b’4’,第3个字节为b’\t’或b’\n’或b’\r’pgmPortable Graymap Files第1个字节为b’P’,第2个字节为b’2’或b’5’,第3个字节为b’\t’或b’\n’或b’\r’ppmPortable Pixmap Files第1个字节为b’P’,第2个字节为b’3’或b’6’,第3个字节为b’\t’或b’\n’或b’\r’rastSun Raster以字节串b’\x59\xA6\x6A\x95’开头xbmX Bitmap Files以字节串b’#define ‘开头bmpBitmap,Windows标准图像文件格式以字节串b’BM’开头webp谷歌的WebP格式,Python3.5加入以字节串b’RIFF’开头并且第9到第12个字节为b’WEBP’exrOpenEXR,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
