1

gimp has the ability to generate a palette from a loaded image. I am looking to have all images (i am not necessarily the author of these pictures) share a common palette since this makes it easier displaying them on an LCD screen.

is there a program that does this? or some script in gimp or imagemagick?

Spektre
  • 49,595
  • 11
  • 110
  • 380
rombios
  • 11
  • 2
  • In Gimp you would: 1) load all JPEGs as layers 2) use gimp_image_convert_indexed() to dither them all 3) possibly export the palette 4) iterate/save each layer. But number of files depends on available memory, and the palette is 256 colors max, while LCDs can display more than 256 colors? – xenoid Apr 19 '17 at 08:18

2 Answers2

1

There are few ways to do this:

  1. use dithering

    with palette designed for dithering like default VGA or WEB palette. I do it like this:

    on how to do this. There are also more sophisticated approaches for this out there just google dithering...

  2. merge all images to single mosaic

    and compute the palette for this big image containing all the images you want with tool you use now. After that just use this palette for each of the original images (or on the mosaic and then de-mosaic).

  3. compute the palette yourself

    You need to compute histogram of all images and then use some kind of clustering to lower the number of colors. To include more images to this just compute histogram for all the images (do not reset it between images) and the rest is same as for single image. So if you got access to the color quantization code of yours then just change the histogram part ... by adding loop through all the images you want (and clearing histogram just for the first image).

    Here example of how I do the color quantization:

I do not use gimp nor imagemagick so I can not help you there but now you at least know what to look for in their docs ...

Community
  • 1
  • 1
Spektre
  • 49,595
  • 11
  • 110
  • 380
1

I'm not sure what you are trying to do is applicable to JPEG images as they do not have a colour palette. However, a possible technique with ImageMagick at the command line would be to put all the images together, reduce the number of colours to whatever you want and then save that (minimised/de-duplicated) as a "palette" which you can apply to other images.

So, the first step is to extract a common palette, of say 250 colours:

magick image1.jpg image2.jpg ... +append -colors 250 -unique-colors palette.png

Now, before you display any image, map it to that palette:

magick image.jpg -remap palette.png result.png

You can also disable dithering, with:

magick +dither image.jpg -remap palette.png result.png

I have used PNG rather than JPEG throughout because of my issue with JPEG palettes, but you can try with your JPEGs using just the same commands. I would definitely suggest you use GIF, PNG or NetPBM PPM format to store the palette information at least.


Just for fun, let's try that with a picture of the White House:

enter image description here

Let's make a really poor palette of three colours - red, yellow and cyan:

convert xc:red xc:yellow xc:cyan +append palette.png

enter image description here

and apply it with dither:

convert whitehouse.jpg -remap palette.png dither.png

enter image description here

and again without:

convert whitehouse.jpg +dither -remap palette.png undither.png

enter image description here

As @Spektre points out in the comments below, you may be passing that palette to the LCD in some BYTE array or something like a lookup table. If that is the case, you can see the palette in human/ASCII terms like this:

convert palette.png txt:

# ImageMagick pixel enumeration: 3,1,65535,srgb
0,0: (65535,0,0)  #FF0000  red
1,0: (65535,65535,0)  #FFFF00  yellow
2,0: (0,65535,65535)  #00FFFF  cyan

And you can get a 9-byte file of the R, G & B values in binary like this - I am choosing to dump it in hex afterwards so you can see it:

convert palette.png -depth 8 rgb:palette.bin

xd palette.bin
00000000: ff00 00ff ff00 00ff ff                   .........
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • The output is most likely not in JPG but some BYTE array for the LCD with some indexed colors format instead... but you're right if (s)he needs to store the sub-results JPG is out of question ... unless the LCD does the conversion on it self but not as good and converting to common colors have better visual quality ... – Spektre Apr 19 '17 at 08:47
  • @Spektre Thanks for the insights - I am not very familiar with LCDs, so I will add some more information that may be useful now you have explained the BYTE array. Thanks again. – Mark Setchell Apr 19 '17 at 08:50
  • 1
    I am just guessing here but I do have low level HW background LCD's included so it is an educated guess ... – Spektre Apr 19 '17 at 08:53