0

I would like to know how to change more than one pixel value in a mode P image with PIL.
In my case I have 3 pixels values: 0, 1 , 2. I would map them respectively to 255, 76, 124.
I tried:

Image.open(my_image).point(lambda p: 255 if p==0 else (76 if p==1 else 124))

When I run the code above, I get an image with all black pixels.

Why?
Sholud I use a different function rather than point()?

Update:
.getpalette() returns {0, 255}

Simone
  • 4,800
  • 12
  • 30
  • 46
  • 1
    Have a look here... https://stackoverflow.com/a/71511757/2836621 and here https://stackoverflow.com/a/72729002/2836621 – Mark Setchell Sep 09 '22 at 17:46
  • If you still don't have the answer you should post your image and your minimal, complete, runnable code. – Mark Setchell Sep 11 '22 at 16:36
  • @MarkSetchell This code works properly: `def show_mask(mask): return Image.open(mask).point(lambda p: 255 if p==0 else 0)`. I don't know why it does not work with 3 colors substitution – Simone Sep 12 '22 at 17:08
  • As I said above, if you still don't have the answer, please post your image and minimal, complete, runnable code so that folks can help you. – Mark Setchell Sep 12 '22 at 17:41

1 Answers1

1

If all pixels in your image with the same value mapping to the same output value sounds fine, then Image.point() is definitely the right way to go.

Now why you're getting a black image depends on the color values defined in the palette. You can check the image's palette by calling Image.getpalette(). If your palette defines only 3 color values and anything beyond index 9 in the palette data is 0, then you should map your pixel data in that range, anything other than that will map to the default black.

If you want to use other color values than these defined in your palette, then consider converting to other color modes before calling Image.point():

Image.open(my_image).convert('L').point(lambda p: 255 if p==0 else 76 if p==1 else 124)
hhimko
  • 145
  • 9