1

I'm using Pillow (version 5.2.0) on Python3 to open both PNG and BMP images, and display them with a Tkinter GUI. The PNG images display correctly with no issues, however, I'm encountering an IOError ("Unsupported BMP compression") with some of the BMP images, when Pillow's BmpImagePlugin.py is used.

Using the bitmap plugin's source and some print statements, I found that the exception is thrown at line 193, and that the images causing the exception are compressed using RLE8 (denoted by the dictionary on line 63); all others work because they're a RAW format. It would seem to me that if a compression type is listed in that dictionary it should be supported, but apparently that isn't the case.

My question: is anyone aware of a workaround in Pillow or of any other python library that can open RLE8 bitmap images? Here's an image displaying my PATH environment, as well as the command-line error described in a comment below.

Edit:

Path issues

2nd Edit

bbotezatu
  • 25
  • 7
  • Do you have an *"unhappy "* RLE8 image lying around that you can share for testing please? – Mark Setchell Oct 03 '18 at 06:56
  • That appears to be PNG rather than BMP. – Mark Setchell Oct 07 '18 at 18:03
  • Sorry, the hosting website converted it. This one should work http://www.filedropper.com/test_1995 – bbotezatu Oct 08 '18 at 16:21
  • That link doesn't seem to work either. – Mark Setchell Oct 22 '18 at 18:06
  • Sorry about that Mark; the website decided to delete my images. I've created a GitHub issue that has three images in a zip file at the bottom. https://github.com/python-pillow/Pillow/issues/3425 – bbotezatu Oct 22 '18 at 19:04
  • Mark, I noticed that in order to install pyvips, [libvips](https://libvips.github.io/libvips/install.html) is also needed. Are you aware of any way to install them both programmatically? By that I mean, with Pillow I was able to run 'pip install pillow' in powershell, and then simply import Pillow in my python program, and it worked. Is it possible to do that with pyvips? – bbotezatu Oct 26 '18 at 20:00
  • Sorry, not sure, I don’t use Windows or Powershell. Maybe @user894763 would know as he developed and maintains `pyvips`. – Mark Setchell Oct 26 '18 at 20:46

1 Answers1

1

I note that your first image (test1.bmp) appears to be corrupt and ImageMagick reports it has incorrect length.

Your second image does not appear to be compressed with RLE8 compression and also is a palettised image, but with alpha/transparency.

Your third image is palletised, non-alpha with RLE8 compression.

My version of PIL can read only the second file - the first and third, which are RLE encoded cannot be read.


You asked for a workaround - may I suggest pyvips which can read the files without issues:

import pyvips
from PIL import Image

# Load troublesome file using vips, and write to a memory buffer
image = pyvips.Image.new_from_file('test1.bmp')
mem_img = image.write_to_memory()

# Read from memory buffer into Numpy array
imgnp=np.frombuffer(mem_img, dtype=np.uint8).reshape(image.height, image.width, 3)
# Convert Numpy array to PIL Image and write to disk
Image.fromarray(imgnp).save('result.png')
jcupitt
  • 10,213
  • 2
  • 23
  • 39
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Oh no problem, just a tiny thing. Thanks for mentioning pyvips! – jcupitt Oct 25 '18 at 17:16
  • @jcupitt : would it be possible to install pyvips programmatically (as mentioned above in my comment on my question)? – bbotezatu Oct 30 '18 at 03:50
  • Hi, sure, download the libvips zipfile from eg. https://github.com/libvips/libvips/releases/download/v8.7.0/vips-dev-w64-all-8.7.0.zip then unzip, add the `vips-x.y.z/bin` dir to `%PATH%`, run `pip install pyvips` and launch Python. – jcupitt Oct 30 '18 at 08:46
  • I uninstalled and then reinstalled all components according to instructions you posted [here](https://github.com/libvips/pyvips/issues/44#issuecomment-390160980), and running `vips` in command line gives me the same result as [this](https://github.com/libvips/pyvips/issues/44#issuecomment-394628537) individual, but then attempting to run `import pyvips` results in an error, the last line reads `cannot load library 'C:\vips-dev-8.7\vips-dev-8.7\bin\libgobject-2.0-0.dll': error 0xc1`, any suggestions? I tried reordering C:\vips-dev-8.7\vips-dev-8.7\bin to top of path variables, no success there. – bbotezatu Nov 02 '18 at 21:07
  • `PATH` variable, or `PYTHONPATH` surely? – Mark Setchell Nov 02 '18 at 21:22
  • @MarkSetchell I have to admit, I haven't heard of `PYTHONPATH` before. I moved vips to the top of my environment variables, by way of `My Computer > Properties > Advanced System Settings > Environment Variables`. I lament the fact that I can't post a picture on an SO comment.. – bbotezatu Nov 03 '18 at 00:21
  • You can click `edit` under your original question and add images. – Mark Setchell Nov 04 '18 at 10:20
  • Thanks, I included one up top. @jcupitt, would it help at all to try and recompile from the source tar.gz? – bbotezatu Nov 06 '18 at 18:17
  • You probably have a DLL conflict. I would set PATH from within Python instead. I've revised the install instructions here: https://github.com/libvips/pyvips/#install-pyvips I tested and it seems fine on my win10 PC, let me know if it works for you. – jcupitt Nov 07 '18 at 11:46
  • I wouldn't try building libvips yourself on Windows, unless you are very skilled. It's probably a week's work for an experienced developer. There's an automated build system here: https://github.com/libvips/build-win64 it might make a useful starting point. – jcupitt Nov 07 '18 at 11:54
  • @jcupitt I tried the update suggestion, but got the same result, I posted an image above. – bbotezatu Nov 14 '18 at 06:35
  • I know very little about Windows, but would point out that your Python looks 32-bit to my untrained eye and John's notes look 64-bit. I may be completely wrong, I'm just saying... – Mark Setchell Nov 14 '18 at 07:18
  • 1
    Yes, I agree with Mark, I think you have a 32-bit Python. You need 64-bit for the official libvips binary. – jcupitt Nov 14 '18 at 09:02
  • That was it, thanks! I changed to 64-bit; checked with `sys.version` and now the program is running with 3.7.1 64-bit, and I can import pyvips without any issues. however, when I try Mark's above workaround in my program, it's throwing the following error: `imgnp = np.frombuffer(mem_img, dtype=np.uint8).reshape(image.height, image.width, 3) ValueError: cannot reshape array of size 480000 into shape (600,800,3)` – bbotezatu Nov 14 '18 at 23:37
  • Ok, I'm now going to guess your image is greyscale and therefore only has 1 channel of grey values, rather than three channels of RGB. If so, you need `reshape(600,800)` or maybe `reshape(600,800,1)`. – Mark Setchell Nov 15 '18 at 07:16
  • That worked perfectly. Thanks, @MarkSetchell and jcupitt, for your patience and your help with all of this. – bbotezatu Nov 17 '18 at 15:51
  • Cool - good luck with your project. Many thanks, as always to John @jcupitt – Mark Setchell Nov 17 '18 at 17:52
  • @jcupitt Sorry to bother again, just a quick question: there aren't any issues with pyvips/libvips on Windows 7, are there? Asking because I'm trying to now implement this fix on an older device, and it isn't performing as expected. – bbotezatu Feb 27 '19 at 17:47
  • Sorry, no idea :( It used to work (I used libvips on NT back in the day), but I've only tried the current build on win10. – jcupitt Feb 27 '19 at 18:14
  • I'm getting this, `VipsForeignLoad: "test.bmp" is not a known file format`, although those same images displayed on W10. Would there be any **kwargs/load option I could try for `new_from_file()` that could fix this error, or does the W7 OS simply not support some features of libvips? I wasn't able to find a 'vips jpegload' for bitmaps. – bbotezatu Mar 01 '19 at 20:07