-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Handle alpha values #3
Comments
Hello, I dont know if this is exactly what you are looking for here, but I got a use case when I had to get rid of background(alpha=0) pixels, a.k.a not to count their color, and I solved easily. I could make a PR if you want. Im gonna leave the code here in any case. import collections
from PIL import Image, ImageDraw
from extcolors import conversion
from extcolors import difference
DEFAULT_TOLERANCE = 32
class Color:
def __init__(self, rgb=None, lab=None, count=0):
self.rgb = rgb
self.lab = lab
self.count = count
self.compressed = False
def __lt__(self, other):
return self.count < other.count
def extract_from_image(img, tolerance=DEFAULT_TOLERANCE, limit=None, transparence=False):
pixels = load(img, transparence)
colors = count_colors(pixels)
colors = compress(colors, tolerance)
if limit:
limit = min(int(limit), len(colors))
colors = colors[:limit]
colors = [(color.rgb, color.count) for color in colors]
return colors, len(pixels)
def extract_from_path(path, tolerance=DEFAULT_TOLERANCE, limit=None, transparence=False):
img = Image.open(path)
return extract_from_image(img, tolerance, limit, transparence)
def load(img, transparence):
if transparence:
img = img.convert("RGBA")
return list(filter(lambda x: x[3] > 0, img.getdata()))
else:
img = img.convert("RGB")
return list(img.getdata())
def count_colors(pixels):
counter = collections.defaultdict(int)
for color in pixels:
counter[color] += 1
colors = []
for rgb, count in counter.items():
lab = conversion.rgb_lab(rgb)
colors.append(Color(rgb=rgb, lab=lab, count=count))
return colors
def compress(colors, tolerance):
colors.sort(reverse=True)
if tolerance <= 0:
return colors
i = 0
while i < len(colors):
larger = colors[i]
if not larger.compressed:
j = i + 1
while j < len(colors):
smaller = colors[j]
if not smaller.compressed and difference.cie76(
larger.lab, smaller.lab) < tolerance:
larger.count += smaller.count
smaller.compressed = True
j += 1
i += 1
colors = [color for color in colors if not color.compressed]
colors.sort(reverse=True)
return colors This is the full code in the modified __init__.py file. Its quite silly actually, its just about adding a boolean |
Thank you for sharing your solution, much appreciated. I like the idea to remove anything with zero alpha, it feels intuitive. I will use you idea to setup some tests and investigate further, hopefully I will have some time during the weekend. I haven't had a use case for images with transparency yet and not sure what would be a desired way to handle alpha that isn't either zero or full. I imagine a blend option would be of interest to be able to decide how the result should be affected. Is this something you encounter in your scenario? |
No description provided.
The text was updated successfully, but these errors were encountered: