Skip to content
/ palgen Public

Create a palette of N colors or convert True Color images to indexed ones. Includes png2gpl and png2act.

License

Notifications You must be signed in to change notification settings

xyproto/palgen

Repository files navigation

palgen Build GoDoc Go Report Card

Render, extract and save palettes

Given an image, create a palette of N colors, or convert True Color images to indexed ones.

Palettes can also be rendered as images.

Included utilities

  • png256, for converting a True Color PNG image to an indexed PNG image, with a custom palette of 256 colors.
  • png2png, for extracting a palette from a True Color PNG image and write the palette as an indexed 256 color PNG image.
  • png2gpl, for extracting a palette from a True Color PNG image and write the palette as a GIMP palette file (.gpl).
  • png2act, for extracting a palette from a True Color PNG image and write the palette as a Photoshop palette file (.act).

Palette extraction

source image extracted 256 color palette
png png
png png

The palette can be extracted and saved as a PNG image, using png2png, or as a GIMP palette, using png2gpl.

Palettes can be sorted by hue, luminance and chroma, using the HCL colorspace and the go-colorful package, with the included palgen.Sort function. The above palettes are sorted with this method.

Features and limitations

  • Can generate palettes of N colors relatively quickly.
  • The palette is generated by first grouping colors into N intensity levels and then use the median color of each group.
  • The generated palette is not 100% optimal, but it's usable.
  • Can export any given color.Palette to a GIMP .gpl palette file.
  • Can export any given color.Palette to a Photoshop .act palette file.
  • Can convert True Color image.Image images to indexed image.Paletted images.

Example use

// Read a PNG file
imageData, err := os.Open("input.png")
if err != nil {
    return err
}

// Decode the PNG image
img, err := png.Decode(imageData)
if err != nil {
    return err
}

// Generate a palette with 256 colors
pal, err := palgen.Generate(img, 256)
if err != nil {
    return err
}

// Output a .gpl palette file with the name "Untitled"
err = palgen.Save(pal, "output.gpl", "Untitled")
if err != nil {
    return err
}

Image comparison

The palettes are generated by palgen

8 color palette 16 color palette 32 color palette 64 color palette 128 color palette 256 color palette original
png png png png png png png
png png png png png png png

Algorithm

A palette is generated by first dividing the colors in the image into N groups, sorted by intensity. For each group, the median value is used. When the number of colors in a group is even, the average of the two center colors are used as the median, but the two center colors are saved for later and added to the generated palette if there are duplicate colors, adding the most used colors first. The generated palette may be shorter than N if there are not enough colors in the given image. As far as I know, no other software uses this algorithm. It works fine, and is relatively fast, but there even better algorithms out there if you are looking for the optimal palette and want to adjust for which colors the human eye are most sensitive for.

As far as I am aware, this is a unique algorithm that has not been thought of or implemented before (create an issue if not), so I'll hereby name it "Rodseth's Median Intensity Algorithm".

Render existing palettes to images

palgen can also be used for rendering palettes to images. Here are the two built-in palettes in the Go standard library, with and without the colors sorted:

Sorted Original
png png
Sorted Original
png png

And one extra:

Sorted Original
png png

General info