Skip to content

Instantly share code, notes, and snippets.

@adammathes
Created August 17, 2013 19:07
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adammathes/6258303 to your computer and use it in GitHub Desktop.
Save adammathes/6258303 to your computer and use it in GitHub Desktop.
Given an input image color palette, extracts all colors from it and generates a color lookup table texture suitable for use with GPUImageLookupFilter of using closest color logic.
#!/usr/bin/python
from PIL import Image, ImageColor
import math
import sys
def closest_color(incolor, colors):
distances = []
min_distance = 10000
for color in colors:
distance = math.sqrt((color[0]-incolor[0])**2+(color[1]-incolor[1])**2+(color[2]-incolor[2])**2)
if(distance < min_distance):
min_distance = distance
c = color
if distance == 0:
return c
return c
def read_colors(filename):
color_hash = {}
i = Image.open(filename)
img = i.convert('RGB')
(width, height) = img.size
for x in range(width):
for y in range(height):
# print img.getpixel( (x,y) )
color_hash[img.getpixel( (x,y) )] = True
return color_hash.keys()
def generate_clut(colors, outfile):
im = Image.new("RGBA", (512, 512))
for by in range(8):
for bx in range(8):
for g in range(64):
for r in range(64):
x = r + bx*64
y = g + by*64
rc = min(255, int(r * 255.0 / 63.0 + 0.5))
gc = min(255, int(g * 255.0 / 63.0 + 0.5))
bc = min(255, int((bx + by * 8.0) * 255.0 / 63.0 + 0.5))
im.putpixel( (x,y), closest_color((rc,gc,bc), colors) )
im.save(outfile)
if len(sys.argv)<3:
print "usage: generate_clut input_image clut.png"
sys.exit();
input_image = sys.argv[1]
output_image = sys.argv[2]
print "reading colors from %s" % input_image
colors = read_colors(input_image)
print "number of colors: %i" % len(colors)
print "generating color lookup table"
generate_clut(colors, output_image)
print "saved to %s" % output_image
@allaze-eroler
Copy link

hello, i have an issue with this python, i always get this kind of error:

from PIL import Image, ImageColor
ModuleNotFoundError: No module named 'PIL'

what should i do?

@allaze-eroler
Copy link

allaze-eroler commented Oct 21, 2022

nevermind, i managed to fix the problem, i also made some modification with the help of my buddies on your code because it's giving some error, so here the fixes:

#!/usr/bin/env python3

import argparse
import math
import os
import sys
from PIL import Image, ImageColor

def closest_color(incolor, colors):
    distances = []
    min_distance = 10000
    for color in colors:
        distance = math.sqrt((color[0]-incolor[0])**2+(color[1]-incolor[1])**2+(color[2]-incolor[2])**2)        

        if(distance < min_distance):
            min_distance = distance
            c = color

        if distance == 0:
            return c

    return c
            
def read_colors(filename):
    color_hash = {}
    i = Image.open(filename)
    img = i.convert('RGB')
    (width, height) = img.size
    for x in range(width):
        for y in range(height):
            # print img.getpixel( (x,y) )
            color_hash[img.getpixel( (x,y) )] = True
    return color_hash.keys()

def generate_clut(colors, outfile):
    im = Image.new("RGBA", (512, 512))
    for by in range(8):
        for bx in range(8):
            for g in range(64):
                for r in range(64):
                    x = r + bx*64
                    y = g + by*64

                    rc = min(255, int(r * 255.0 / 63.0 + 0.5))
                    gc = min(255, int(g * 255.0 / 63.0 + 0.5))
                    bc = min(255, int((bx + by * 8.0) * 255.0 / 63.0 + 0.5))
                    im.putpixel( (x,y), closest_color((rc,gc,bc), colors) )
    im.save(outfile)

def build_parser():
    parser = argparse.ArgumentParser(description="Generate clut")
    parser.add_argument("input_image", action="store", help="The image to generate a clut from")
    parser.add_argument("output_image", action="store", help="Where to save the generated clut")
    return parser

if __name__ == '__main__':
    parser = build_parser()
    args = parser.parse_args(['input_image.png', 'output_image.png'])
    print(f"reading colors from {args.input_image}")
    colors = read_colors(args.input_image)
    print(f"number of colors: {len(colors)}")
    print("generating color lookup table")
    generate_clut(colors, args.output_image)
    print(f"saved to {args.output_image}")

i hope that will solve the problem for those who try to use it to create a custom lut file.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment