From edc406d9dee34d5ee8ecb21c415682fb145456f9 Mon Sep 17 00:00:00 2001 From: Elana Hashman Date: Mon, 26 Oct 2020 21:09:12 -0700 Subject: [PATCH 1/2] Optimize palette selection for non-indexed images --- README.md | 1 + ih/palette.py | 9 +++++---- test_image.jpg | Bin 0 -> 15312 bytes tests/test_cli.py | 9 +++++++-- 4 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 test_image.jpg diff --git a/README.md b/README.md index bdc3ca7..af8fc5a 100644 --- a/README.md +++ b/README.md @@ -141,3 +141,4 @@ LEGO® is a registered trademark of The Lego Group. PERLER BEADS is a trademark of Stitch Acquisition Group. +Aurora test image (`test_image.jpg`) by Jonathan Bean from Unsplash: https://unsplash.com/photos/Ejpx_sdKEKo diff --git a/ih/palette.py b/ih/palette.py index 547b3f6..8a2632e 100644 --- a/ih/palette.py +++ b/ih/palette.py @@ -91,11 +91,12 @@ def reduce_palette(palette, image): best_colours = set() # Get image palette in RGB triplets - my_colours = [x[0:3] for x in image.getdata()] + im = image.convert("P", palette=Image.ADAPTIVE, colors=256) + image_palette = im.getpalette() + my_colours = [] + for i in range (0, len(image_palette), 3): + my_colours.append(image_palette[i:i+3]) - # Larger palettes may take some time, so let 'em know. - if len(my_colours) > 12: - print("Processing...") # Get nearest colour https://stackoverflow.com/a/22478139 tree = sp.KDTree(palette_triplets) for colour in my_colours: diff --git a/test_image.jpg b/test_image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..acc5cfb160ab1e4fb010a288163758e9c48e115e GIT binary patch literal 15312 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 J`;mwF{{d_GY Date: Mon, 26 Oct 2020 22:27:28 -0700 Subject: [PATCH 2/2] Fix order of operations in processing image --- ih/chart.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ih/chart.py b/ih/chart.py index c86c3dc..bcf5311 100644 --- a/ih/chart.py +++ b/ih/chart.py @@ -53,17 +53,17 @@ def preprocess_image( scale=DEFAULT["scale"], guidelines=DEFAULT["guidelines"], ): + # Reduce palette to max 256 colors + reduced_palette = palette.reduce_palette(palette=pal, image=im) + palette_image = palette.get_palette_image(reduced_palette) + im = im.resize((int(im.width / scale), int(im.height / scale))) + # Remove black transparency issues with this one weird trick. alpha = im.convert("RGBA").split()[-1] bg = Image.new("RGBA", im.size, (255, 255, 255, 255)) bg.paste(im, mask=alpha) im = bg - # Reduce palette - reduced_palette = palette.reduce_palette(palette=pal, image=im) # cap palette size at 256 - palette_image = palette.get_palette_image(reduced_palette) - im = im.resize((int(im.width / scale), int(im.height / scale))) - im = ( im.convert("RGB") .convert("P", palette=Image.ADAPTIVE, colors=colors)