From d843c5c198194d6f0c03032122f0a58c88d1c4de Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 28 Aug 2019 22:51:28 +0200 Subject: [PATCH] deploy-ng: use median cut algorithm when palettizing icon This prevents infrequently occurring colors from being washed out. See #718 --- direct/src/p3d/DeploymentTools.py | 29 ++++------------------------- 1 file changed, 4 insertions(+), 25 deletions(-) diff --git a/direct/src/p3d/DeploymentTools.py b/direct/src/p3d/DeploymentTools.py index b67d4d69be..ebc20bfda9 100644 --- a/direct/src/p3d/DeploymentTools.py +++ b/direct/src/p3d/DeploymentTools.py @@ -384,35 +384,14 @@ class Icon: elif bpp == 8: # We'll have to generate a palette of 256 colors. hist = PNMImage.Histogram() - if image.hasAlpha(): - # Make a copy without alpha channel. - image2 = PNMImage(image) + image2 = PNMImage(image) + if image2.hasAlpha(): image2.premultiplyAlpha() image2.removeAlpha() - else: - image2 = image + image2.quantize(256) image2.make_histogram(hist) colors = list(hist.get_pixels()) - if len(colors) > 256: - # Palette too large; remove infrequent colors. - colors.sort(key=hist.get_count, reverse=True) - - # Find the closest color on the palette matching each color - # that didn't fit. This is certainly not the best palette - # generation code, but it'll do for now. - closest_indices = [] - for color in colors[256:]: - closest_index = 0 - closest_diff = 1025 - for i, closest_color in enumerate(colors[:256]): - diff = abs(color.get_red() - closest_color.get_red()) \ - + abs(color.get_green() - closest_color.get_green()) \ - + abs(color.get_blue() - closest_color.get_blue()) - if diff < closest_diff: - closest_index = i - closest_diff = diff - assert closest_diff < 100 - closest_indices.append(closest_index) + assert len(colors) <= 256 # Write the palette. i = 0