Created
April 15, 2017 17:35
-
-
Save pineapplemachine/d8fe2e28becededb27cdf76e02dcf526 to your computer and use it in GitHub Desktop.
Palette coverage visualization tool
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /// This program reads an image from the path "palette.png", finds every unique | |
| /// color in the image, and outputs a visualization to "visualpal.png" which | |
| /// visualizes palette coverage by using white to represent colors very closely | |
| /// representable by colors in the palette and black to represent colors that | |
| /// are relatively distant from any color in the palette. | |
| /// Try it with your favorite palette, for example the NES palette! | |
| /// https://upload.wikimedia.org/wikipedia/en/8/80/NES_palette_color_test_chart.png | |
| /// Written using mach commit e1e9c781fc69fe92fa4c632352c601fdd9a62d18 | |
| /// https://github.com/pineapplemachine/mach.d/commit/e1e9c781fc69fe92fa4c632352c601fdd9a62d18 | |
| /// See mach's readme for installation and usage instructions. | |
| import mach.sdl; | |
| import mach.math; | |
| import mach.collect; | |
| import mach.io.stdio; | |
| import mach.range; | |
| import mach.meta; | |
| /// Compute a distance between two colors. | |
| auto distance(in Color a, in Color b){ | |
| return ((a.r - b.r) ^^ 2 * 0.3 + (a.g - b.g) ^^ 2 * 0.6 + (a.b - b.b) ^^ 2 * 0.1) ^^ 0.5; | |
| } | |
| /// Compute the minimum distance between a color and every color in a set. | |
| auto distance(in Color color, in Set!Color* colors){ | |
| return colors.map!(c => c.distance(color)).top; | |
| } | |
| void main(){ | |
| SDL.load(); | |
| SDL.Support.Default.initialize(); | |
| stdio.writeln("Reading palette image."); | |
| auto pal = new Surface("palette.png"); | |
| auto colors = new Set!Color(); | |
| foreach(x; 0 .. pal.width){ | |
| foreach(y; 0 .. pal.height){ | |
| colors.add(pal.getpixel(x, y)); | |
| } | |
| } | |
| stdio.writeln("Found ", colors.length, " unique colors."); | |
| double maxdistance = 0; | |
| Color maxdistcolor; | |
| stdio.writeln("Finding the most distant color."); | |
| auto visual = new Surface(4096, 384); | |
| foreach(r; 0 .. 64){ | |
| foreach(g; 0 .. 64){ | |
| foreach(b; 0 .. 64){ | |
| auto color = Color(r / 63.0, g / 63.0, b / 63.0); | |
| auto dist = distance(color, colors); | |
| if(dist > maxdistance){ | |
| maxdistance = dist; | |
| maxdistcolor = color; | |
| } | |
| } | |
| } | |
| } | |
| stdio.writeln("Most distant color by ", maxdistance, ": ", maxdistcolor.bytes); | |
| stdio.writeln("Generating visualization image."); | |
| foreach(r; 0 .. 64){ | |
| foreach(g; 0 .. 64){ | |
| foreach(b; 0 .. 64){ | |
| auto color = Color(r / 63.0, g / 63.0, b / 63.0); | |
| auto dist = distance(color, colors); | |
| foreach(pix; [ | |
| vector(r + g * 64, b + 0), | |
| vector(g + b * 64, r + 128), | |
| vector(b + r * 64, g + 256), | |
| ]){ | |
| visual.putpixel(pix.x, pix.y, color); | |
| visual.putpixel(pix.x, pix.y + 64, Color(1 - dist / maxdistance)); | |
| } | |
| } | |
| } | |
| } | |
| stdio.writeln("Writing visualization to output file."); | |
| visual.save("visualpal.png"); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment