1

I use a simple line to break an indexed image 256 color into palette using

import numpy as np
from PIL import Image

im = Image.open('')
palette = np.array(im.getpalette(),dtype=np.uint8).reshape((256,3))

#####################
Printed result
[[  1   3   0]
[  2   4   1]
 [ 28   0   4]
 [ 20   2  26]
 [ 24   5  18]
 [ 33   7  22]
 [ 36   7  12]
 [  0  20  18]
 [ 42  15  16]
 [ 43  18  30]

... etc

Printing 'palette' lists the colors as RGB values as listed from index 0 onward. Index 0 is often dark color or black. In some engines it is used for alpha, transparency. I want to use commonly used colors for transparency like Magenta 255 0 255

I want to take each of my png files in a folder and do batch (I will have to manually add the color to the images, then save them as 8 bit so the color is part of the palette) then do:

  • exchange position of index 0 color with the Magenta in the color map
  • position of magenta color will vary for each file, just find the color 255 0 25 and replace color at index 0 with it but also take the index 0 color and put it on magenta place
  • do for all .png files in folder with a single run (magenta will be added and images indexed before running the script) enter image description here

This is an image where Magenta isnt first color of image palette Here is how it should be as final result

programc7r
  • 63
  • 6
  • 1
    If, as it seems, you are just starting on this project, why are you using Python 2.7 as it went *"End of Life"* months ago? – Mark Setchell May 13 '20 at 10:16
  • It can be python3 I don't mind, I don't know how to take an item as index when it is with spaces broken into 3 numbers – programc7r May 13 '20 at 13:57
  • Please provide a suitable input image. Thank you. – Mark Setchell May 13 '20 at 14:24
  • What is unsuitable about it? This is a color map, im tring to swap two colors in the palette also listed in the script. How do I find '255 0 255' when it won't read it from the indices even if I printed the index of it, and swap the values with index 0 while put the index 0 values (usually black colors) on the place of where Magenta used to be? And that for all png files in a folder – programc7r May 13 '20 at 15:08
  • It is screen-grab of two different images, and as such is no longer a palette image like you say you have. Instead it is RGB with 411 colours. Secondly, it also has an alpha channel. – Mark Setchell May 13 '20 at 15:11
  • Ok here are two images of that kind, on left u see pure black because ur background is black.But when you swap you see that there is a box in the center. I swapped them manually with Gimp now I want to batch swap them for every image, some images may not have the Magenta at exact same place, so I need to find the Index containing 255 0 255 and swap Index 0 with each other, always Index 0 for all files – programc7r May 13 '20 at 15:39

1 Answers1

1

I think you want something like this:

#!/usr/bin/env python3

import numpy as np
from PIL import Image

# Open image
im = Image.open('image.png')

# Extract palette
palette = np.array(im.getpalette(),dtype=np.uint8).reshape((256,3))

# Look through palette
for index,entry in enumerate(palette): 
    # Swap this entry with entry 0 if this is magenta
    if index>0 and np.all(entry==[255,0,255]): 
        print(f'DEBUG: Swapping entry {index} with entry 0') 
        palette[0], palette[index] = palette[index], palette[0]
        break
else:
    print('ERROR: Did not find magenta entry in palette')

# Replace palette with new one and save    
im.putpalette(palette)
im.save('result.png')

You would probably code it to accept multiple files on the command line like this:

for file in sys.argv[1:]:
    ...
    ...

Then you could run:

UpdatePalette.py *.png
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • Thanks, that does it.One small correction, replacing `palette[0], palette[index] = palette[index], palette[0]` because it then keeps both Index 0 and Index ... as magenta . So I used `palette[index] = palette[0] palette[0] = 255,0,255` As it doesn't remember the old color and copies the value to both but putting the 255 0 255 works and looks like in my 'Wanted result'image. Also use `sprites = glob.glob('*.png') for png in sprites: # Open image im = Image.open(png)` and `im.save(im.filename)` – programc7r May 14 '20 at 15:56
  • Cool - glad we got there in the end! Good luck with your project. – Mark Setchell May 14 '20 at 16:06