不支持的 BMP 压缩 - BMP 到 JPEG - PIL - Python

Posted

技术标签:

【中文标题】不支持的 BMP 压缩 - BMP 到 JPEG - PIL - Python【英文标题】:Unsupported BMP compression - BMP to JPEG - PIL - Python 【发布时间】:2018-09-19 05:08:21 【问题描述】:

我正在尝试使用以下代码将 bmp 图像转换为 jpeg。

from PIL import Image
img = Image.open('/Desktop/xyz.bmp')
new_img = img.resize( (256, 256) )
new_img.save( '/Desktop/abc.png', 'png')

执行时出现错误,

Traceback (most recent call last):   File "D:/widowed_hulk/otokar/image_scraper.py", line 80, in <module>
    img = Image.open('C:/Users/santhosh.solomon/Desktop/bmp/ImageHandler.bmp')   File "C:\Python34\lib\site-packages\PIL\Image.py", line 2609, in open
    im = _open_core(fp, filename, prefix)   File "C:\Python34\lib\site-packages\PIL\Image.py", line 2599, in _open_core
    im = factory(fp, filename)   File "C:\Python34\lib\site-packages\PIL\ImageFile.py", line 102, in
__init__
    self._open()   File "C:\Python34\lib\site-packages\PIL\BmpImagePlugin.py", line 201, in
_open
    self._bitmap(offset=offset)   File "C:\Python34\lib\site-packages\PIL\BmpImagePlugin.py", line 161, in
_bitmap
    raise IOError("Unsupported BMP compression (%d)" % file_info['compression']) OSError: Unsupported BMP compression (1)

我正在尝试转换的图像:https://servis.otokar.com.tr:8083/ImageHandler.ashx?id=6425

谁能指导我解决这个错误?

【问题讨论】:

【参考方案1】:

这不是你自己的错。图像采用awkward Microsoft BMP V3 格式,我相信 RLE 压缩,我不相信 Pillow 可以处理。

您可以像这样在终端中使用 ImageMagick 重写图像而不进行压缩,然后您的代码就可以正常工作了:

convert image.bmp -compress none image.bmp

但如果你这样做,你也可以使用 ImageMagick 来制作 PNG:

convert image.bmp result.png

作为替代方案,如果您想使用 Python,您可以尝试其他一些库,例如 pyvips - 我会尝试并报告。

【讨论】:

感谢您的宝贵时间和回复。我会尝试您的建议,然后回复您的反馈。【参考方案2】:

在尝试了许多可能的方法后,我找到了 openCV 库的解决方案。这不会给我带来任何压缩错误,并且像魅力一样处理转换。

import cv2
image = cv2.imread(img)
cv2.imwrite(imag_name.replace('.bmp', '.jpg'), image)

也感谢@Mark 的建议。因为我必须转换大量图像,而 openCV 似乎可以轻松处理我使用 openCV 的问题。

【讨论】:

干得好,感谢您与社区分享。顺便说一句,您可以接受自己的答案是正确的,并抓住要点:-)【参考方案3】:

就像 Mark Setchell 建议的那样,pyvips确实打开了 RLE 编码且没有任何错误的 BMP,这与我的测试中的 PIL 和 cv2 不同。我想用 PIL 打开 RLE 编码的 BMP,所以我也在使用 numpy,但你不需要。

import os

import numpy as np
from PIL import Image

def get_old_img(input_image_path):
    # pyvips acts as a substitute for PIL and cv2, because both of those can throw a warning in the terminal with RLE bmps.
    pyvips_img = pyvips.Image.new_from_file(input_image_path, access='sequential')
    np_img = vips2numpy(pyvips_img)
    return Image.fromarray(np.uint8(np_img))

format_to_np_dtype = 
    'uchar': np.uint8,
    'char': np.int8,
    'ushort': np.uint16,
    'short': np.int16,
    'uint': np.uint32,
    'int': np.int32,
    'float': np.float32,
    'double': np.float64,
    'complex': np.complex64,
    'dpcomplex': np.complex128,


def vips2numpy(vi):
    return np.ndarray(buffer=vi.write_to_memory(),
                        dtype=format_to_np_dtype[vi.format],
                        shape=[vi.height, vi.width, vi.bands])

get_old_img("input.bmp").show()

我不确定是否有其他人在尝试导入它时通过 pip 安装它来让 pyvips 正常工作,因为它对我造成了错误 OSError: cannot load library 'C:\dev\vips\vips-dev-8.6\bin\libgobject-2.0-0.dll',但你可以通过 both 使用 pip 安装 pyvips 以及从 https://github.com/libvips/libvips/releases 解压缩最新版本的 vips-dev-w64-all.zip 并更新 load_vips_end() 中的 vipshome 字符串。

def load_vips_env():
    vipshome = 'c:\\vips-dev-8.10\\bin'
    os.environ['PATH'] = vipshome + ';' + os.environ['PATH']

load_vips_env()

import pyvips

【讨论】:

以上是关于不支持的 BMP 压缩 - BMP 到 JPEG - PIL - Python的主要内容,如果未能解决你的问题,请参考以下文章

bmp 和JPG有啥区别

JPEG、GIF、PNG、BMP哪种图片格式的图片清晰一点?

jpg rm rar doc bmp wav zip wmv xls ppt各属于啥类

JPEG、GIF、PNG、BMP哪种图片格式的图片清晰一点?

JPG、GIF、PNG和BMP格式的图片各有啥优点和缺点?

图片的四种格式.jpg、.gif、.png、.bmp各是啥意思?