PILLOW throws ValueError: unknown raw mode for given image mode

Question:

I currently use PILLOW to convert some images to base64 for use in a flask API,
It works quite well but for some reason it crashes on a BMP file and I don’t know why.

Here is my code :

def get_img_base64(filename):
    # Open Image
    image = Image.open(filename)
    # Saving the format
    format = image.format
    buffered = BytesIO()
    image.save(buffered, format)
    img_str = base64.b64encode(buffered.getvalue())
    return "data:image/" + format + ";base64," + img_str.decode()

And here is the error I get :

Traceback (most recent call last):
  File "test.py", line XXX, in XXX
    imgBase64 = get_img_base64(path)
  File "test.py", line XXX, in get_img_base64
    image.save(buffered, format)
  File "python3.10/site-packages/PIL/Image.py", line 2264, in save
    self._ensure_mutable()
  File "python3.10/site-packages/PIL/Image.py", line 626, in _ensure_mutable
    self._copy()
  File "python3.10/site-packages/PIL/Image.py", line 619, in _copy
    self.load()
  File "python3.10/site-packages/PIL/ImageFile.py", line 234, in load
    err_code = decoder.decode(b"")[1]
  File "python3.10/site-packages/PIL/BmpImagePlugin.py", line 326, in decode
    self.set_as_raw(bytes(data), ("P", 0, self.args[-1]))
  File "python3.10/site-packages/PIL/ImageFile.py", line 684, in set_as_raw
    d = Image._getdecoder(self.mode, "raw", (rawmode))
  File "python3.10/site-packages/PIL/Image.py", line 435, in _getdecoder
    return decoder(mode, *args + extra)
ValueError: unknown raw mode for given image mode

I already tried this solution by converting the image to "P" but the error ValueError: unknown raw mode for given image mode is also showing on this conversion.

Here is the image in question

Here is the reuslt of the exiftool -v IMG.BMP command :

  ExifToolVersion = 12.40
  FileName = IMG.BMP
  Directory = .
  FileSize = 44978
  FileModifyDate = 1655391432
  FileAccessDate = 1655391514
  FileInodeChangeDate = 1655454712
  FilePermissions = 33272
  FileType = BMP
  FileTypeExtension = BMP
  MIMEType = image/bmp
  + [BinaryData directory, 40 bytes]
  | BMPVersion = 40
  | ImageWidth = 594
  | ImageHeight = 163
  | Planes = 1
  | BitDepth = 8
  | Compression = 1
  | ImageLength = 43900
  | PixelsPerMeterX = 2833
  | PixelsPerMeterY = 2833
  | NumColors = 256
  | NumImportantColors = 256
Asked By: PythonNewbie

||

Answers:

This doesn’t make much sense to me. You appear to have a JPEG, PNG or BMP-encoded image on disk in a file called filename. You then decode/decompress it into memory with:

image = Image.open(filename)

You then re-encode it back to exactly the same format (JPEG/PNG/BMP) as it was using before, but in RAM:

format = image.format
buffered = BytesIO()
image.save(buffered, format)

What is the point of that? You might just as well simply read the already-encoded file from disk:

with open(filename, 'rb') as fd:
   image = fd.read()

It might make sense if you always wanted to encode to a specific format regardless of input format, e.g. always make a PNG or always make a JPEG, but you didn’t say that was the case and it might not be sensible to convert PNGs with transparency to JPEG which cannot support transparency.


It might make sense if you always want to encode to a specific quality setting, but you did’t say that either.


It might make sense if you have some images in a format that flask and the user’s web browser don’t accept, but you didn’t say that either.

Answered By: Mark Setchell

It was an issue with the PILLOW Library. It should be fixed in the next release as this PR suggests

Answered By: PythonNewbie

Adding this line has solved my problem

mask = mask.convert('P')
Answered By: Maadesh Sivakumar
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.