Skip to content

Instantly share code, notes, and snippets.

@clobrano
Created November 2, 2018 16:37
Show Gist options
  • Select an option

  • Save clobrano/fc7060f3dbeb5904b468aa2449bbdbe8 to your computer and use it in GitHub Desktop.

Select an option

Save clobrano/fc7060f3dbeb5904b468aa2449bbdbe8 to your computer and use it in GitHub Desktop.
add background to icon with its dominant color
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# vi: set ft=python :
'''
usage: dominant.py --filename=<path> [--order=<order>] [--npoints=<value>]
options:
-f path, --filename=path Name of the icon
-o value, --order=value Order of the super ellise [default: 4]
-n points, --npoints=npoints Number of points that render the background [default: 50]
'''
import docopt
import os
import sys
from math import pi, cos, sin, pow, fabs, copysign
from PIL import Image, ImageDraw
import svgwrite
def get_dominant_color(image, numcolors=100, resize=150):
image = image.resize((resize, resize))
im = image.convert('P', palette=Image.ADAPTIVE, colors=numcolors)
if im.mode == 'P':
im.putalpha(0)
colors = im.getcolors(resize*resize)
col = sorted(colors, key=lambda x: x[0])
return col[-3][1]
def signed_power(x,y):
"""Returns x to the power y, but preserves the sign of x
This allows us to plot all four quadrants with a single loop and
no additional sign logic"""
return copysign(pow(fabs(x),y) ,x)
def draw_squircle(size, order=4, npoints=50):
power = 2.0 / order
theta = pi * 2.0 / npoints
cx = cy = size / 2.0;
radiusx = radiusy = size / 2.0
points = []
for i in range(npoints):
x = cx + radiusx * signed_power(cos(i*theta), power)
y = cy + radiusy * signed_power(sin(i*theta), power)
points.append((x,y))
return points
def get_img_squircle(points, size, fillcolor, linecolor):
im = Image.new('RGBA', size, 4*(0))
draw = ImageDraw.Draw(im)
draw.polygon(points, fill=fillcolor, outline=linecolor)
return im
#def get_svg_squircle(points, fillcolor, linecol, outfile):
# fillcol = "rgb(%d,%d,%fill" % fillcolor[:3]
# linecol = "rgb(%d,%d,%d)" % linecolor[:3]
# svg_doc = svgwrite.Drawing(filename=outfile)
# svgdoc.add(svgdoc.polygon(points=points, stroke_width="1", fill=fillcol, stroke=linecol))
# return svgdoc
def overlay(icon, background, filename):
"""Overlay icon with background"""
# background = background.resize((icon.width, icon.height))
print('background = %d x %d' % (background.width, background.height))
print('image = %d x %d, %s' % (icon.width, icon.height, icon.mode))
overlay = Image.composite(icon, background, background)
overlay.show()
# Command Line Handling
if __name__ == '__main__' :
args = docopt.docopt(__doc__)
print(args)
icon_name = args['--filename']
icon = Image.open(icon_name).convert('RGBA')
color = get_dominant_color(icon)
order = float(args['--order'])
npoints = int(args['--npoints'])
size = icon.size
points = draw_squircle(size[0], npoints, npoints=npoints)
background = get_img_squircle(points, size, color, color)
# save_img_squircle(points, color, color, 'background.png')
overlay(icon, background, 'new_' + icon_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment