Skip to main content
added 1114 characters in body
Source Link

If you don't like NetPBM, you can do it very simply in Python with Pillow as follows:

#!/usr/bin/env python3 from PIL import Image import numpy as np # Load input image im = Image.open('start.png') # Get palette p = im.getpalette() #print(f'{p=}') # Make new palette, by swapping first and last RGB entries firstEntry = p[:3] print(f'{firstEntry=}') lastEntry = p[-3:] print(f'{lastEntry=}') newPalette = [ *lastEntry, *p[3:765], *firstEntry ] print(f'{len(newPalette)=}') #print(f'{newPalette=}') # Make image into Numpy array of palette indices na = np.array(im) # Find all locations with palette entry 0, and all locations with palette entry 255 mask0 = na==0 mask255 = na==255 # Swap 0 for 255 and 255 for 0 na[mask0] = 255 na[mask255] = 0 # Revert to PIL Image and push in new palette newIm = Image.fromarray(na) newIm.putpalette(newPalette) # Save result as PCX newIm.save('result.pcx') 

Note I have not coded the general case, just the demonstration of swapping palette indices 0 and 255. The other case is not much harder and you can certainly code it from this example. I didn't want to get bogged down in the general case because Python may be a non-starter for you.


If you don't like NetPBM, you can do it very simply in Python with Pillow as follows:

#!/usr/bin/env python3 from PIL import Image import numpy as np # Load input image im = Image.open('start.png') # Get palette p = im.getpalette() #print(f'{p=}') # Make new palette, by swapping first and last RGB entries firstEntry = p[:3] print(f'{firstEntry=}') lastEntry = p[-3:] print(f'{lastEntry=}') newPalette = [ *lastEntry, *p[3:765], *firstEntry ] print(f'{len(newPalette)=}') #print(f'{newPalette=}') # Make image into Numpy array of palette indices na = np.array(im) # Find all locations with palette entry 0, and all locations with palette entry 255 mask0 = na==0 mask255 = na==255 # Swap 0 for 255 and 255 for 0 na[mask0] = 255 na[mask255] = 0 # Revert to PIL Image and push in new palette newIm = Image.fromarray(na) newIm.putpalette(newPalette) # Save result as PCX newIm.save('result.pcx') 

Note I have not coded the general case, just the demonstration of swapping palette indices 0 and 255. The other case is not much harder and you can certainly code it from this example. I didn't want to get bogged down in the general case because Python may be a non-starter for you.

Source Link

It cannot be done with ImageMagick, but you can do it with the NetPBM suite. The trick is to use ppmtopcx with a forced palette.

Here is a script that will do it for you - it is well commented and it creates all the intermediate files in easy-to-view formats:

#!/bin/bash ################################################################################ # Reorder palette of PNG file to put magenta first in palette and make into PCX ################################################################################ # Pick up filename from first parameter, or use "start.png" if none given input=${1:-'start.png'} >&2 echo "Processing file: $input" # Extract palette from original image >&2 echo "Extracting original palette into palette0.txt" magick identify -verbose "$input" | awk ' /Rendering intent:/ {exit} p==1 {print substr($3,2,6)} /Colormap:/ {p=1} ' > palette0.txt # Reorder palette with desired entry (FF00FF) first >&2 echo "Reordering palette into palette1.txt" { printf "FF00FF\n"; grep -v "FF00FF" palette0.txt; } > palette1.txt # Make PPM file with new palette # width will be number of palette entries, height will be 1 w=$(wc -l < palette1.txt) h=1 >&2 echo "Making ${w}x${h} PPM file with new palette in palette.ppm" printf "P6\n$w $h\n255\n" > palette.ppm # Convert textual palette (palette1.txt) to binary and append to PPM we just started above tr -d '#\n' < palette1.txt | xxd -r -p >> palette.ppm # Now convert original image to PPM and pass to "ppmtopcx" forcing the new palette as we go pngtopnm start.png | ppmtopcx -8bit -palette palette.ppm > result.pcx # Dump palette of created PCX file for fun - it's the final 768 bytes tail -c 768 result.pcx | xxd -c12 -g3 

I made a test image guaranteed to include magenta and 255 other colours like this:

magick -size 256x256 gradient:black-magenta start.png 

The dumped palette at the end looks like this:

00000000: ff00ff 000000 010001 020002 ............ 0000000c: 030003 040004 050005 060006 ............ 00000018: 070007 080008 090009 0a000a ............ ... ... 000002dc: f300f3 f400f4 f500f5 f600f6 ............ 000002e8: f700f7 f800f8 f900f9 fa00fa ............ 000002f4: fb00fb fc00fc fd00fd fe00fe ............ 

Hopefully you can see magenta (ff00ff) as the first entry and the that it is missing as the final entry (having been relocated to the start).