1

I'm using a program that requires 4bpp indexed images, I'd like to pad my 1bpp and 2bpp images with black palette entries. How would I go about this using Python? I can't see a method of doing it using PIL.

Matt B
  • 11
  • 1
  • A 4bpp PNG is a rather rare beast! Would you care to say what the program is? I don't think you'll have much luck with PIL, or even **ImageMagick**. Do you have a couple of 1bpp, 2bpp and 4bpp PNGs you could share - I doubt the normal Imgur service will even work, you'll probably need to use a binary sharing service. – Mark Setchell Nov 16 '19 at 10:39
  • 1
    The current version of PIL/pillow appears to only support 8bpp indexed images. – martineau Nov 16 '19 at 11:23
  • It's for a Sega Mega Drive tool that uses images with 16 colours :) – Matt B Nov 20 '19 at 08:54

1 Answers1

1

I tried some experiments with this image and ImageMagick, which is included in most Linux distros and is available for macOS and Windows.

First is the original image, then reduced to 16 colours with dither, then reduced to 16 colours without dithering.

enter image description here enter image description here enter image description here

With dithering:

convert paddington.png -colors 16 d.png

Without dithering:

convert paddington.png +dither -colors 16 e.png

Then I looked at the images produced by ImageMagick and they all have 8bpp! So, I tried using the "venerable" NetPBM suite and found it will create a 4bpp image, so that looks like this:

convert paddington.png +dither -colors 16 ppm:- | pnmtopng > result.png

If I run pngcheck on that, it looks to me like a 4bpp PNG:

pngcheck -vv result.png

Output

File: result.png (4857 bytes)
  chunk IHDR at offset 0x0000c, length 13
    150 x 150 image, 4-bit palette, non-interlaced
  chunk PLTE at offset 0x00025, length 48: 16 palette entries
  chunk IDAT at offset 0x00061, length 4740
    zlib: deflated, 16K window, default compression
    row filters (0 none, 1 sub, 2 up, 3 avg, 4 paeth):
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
      (150 out of 150)
  chunk IEND at offset 0x012f1, length 0
No errors detected in result.png (4 chunks, 56.8% compression).

For the moment, I am suggesting you consider "shelling out" to use ImageMagick and NetPBM.

Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • @Matt: If you'd like to use **ImageMagick**'s functionality more directly from your Python script, see [Can I access ImageMagick API with Python?](https://stackoverflow.com/questions/7895278/can-i-access-imagemagick-api-with-python) – martineau Nov 17 '19 at 01:13
  • Thank you for all the responses. Interestingly I've tried imagemagick via command line but the issue is still there. If I reduce an image to 16 colours and it doesn't contain 16 you end up with an image with a smaller palette than 16. You can manually add extra colours via gimp and then resave but this is laborious as I've over 500 images. – Matt B Nov 20 '19 at 09:21
  • My point was that ImageMagick doesn’t do what you want... that’s why I suggested `pnmtopng` from NetPBM suite. – Mark Setchell Nov 20 '19 at 11:52
  • Excellent I'll have a look at netPBM – Matt B Nov 23 '19 at 13:27
  • Any success with this? – Mark Setchell Dec 02 '19 at 12:18