Skip to content

Instantly share code, notes, and snippets.

Created October 24, 2010 19:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/643865 to your computer and use it in GitHub Desktop.
Save anonymous/643865 to your computer and use it in GitHub Desktop.
A small GUI tool for color generation
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# Author: Izidor Matušov <izidor.matusov@gmail.com>
# Date: 21.10.2010
import os.path
import os
import math
import sys
from random import shuffle
from random import randint
import gtk
import cairo
from xml.etree.ElementTree import ElementTree
maxValue = 65535
def randomColor():
"""Generate random color"""
color = gtk.gdk.Color()
color.red = randint(0, maxValue)
color.green = randint(0, maxValue)
color.blue = randint(0, maxValue)
return color
def color2GrayGrades(color):
return 0.299*color.red + 0.587*color.green + 0.114*color.blue
def colorDistance(a, b):
return math.sqrt((a.red-b.red)**2 + (a.green-b.green)**2 + (a.blue-b.blue)**2)
def generateColor(colors):
"""There goes algorithm for generation of color
@param colors - already existing colors
@return color in hexa format, e.g. '#0ABCDEF"""
maxIteration = 10
threshold = 500
colors = [gtk.gdk.color_parse(color) for color in colors]
for iteration in range(10):
print "Iteration ", iteration
color = randomColor()
difference = maxValue
for tag in colors:
difference = min(difference, colorDistance(color, tag))
print "Minimal difference: ", difference
if difference > threshold:
return color.to_string()
return randomColor().to_string()
class ColorWidget(gtk.DrawingArea):
# Minimum size of a bar
BAR_SIZE = (50, 50)
# How many bars should be in row
BARS_IN_ROW = 20
def __init__(self, colors):
super(ColorWidget, self).__init__()
self.colors = [gtk.gdk.color_parse(color) for color in colors]
shuffle(self.colors)
self.grays = False
self.originalColors = len(self.colors)
self.resizeRequest()
self.connect("expose-event", self.expose)
def expose(self, widget, event):
cr = widget.window.cairo_create()
# Compute width and height of bar
widget_width, widget_height = widget.window.get_size()
width, height = (widget_width / self.BARS_IN_ROW, widget_height / self.rows)
# Value for normalization of color
maxValue = 65535.0
# Position
x, y = (0, 0)
for color in self.colors:
if self.grays:
c = color2GrayGrades(color)/float(maxValue)
cr.set_source_rgb(c, c, c)
else:
r = color.red/float(maxValue)
g = color.green/float(maxValue)
b = color.blue/float(maxValue)
cr.set_source_rgb(r, g, b)
cr.rectangle(x * width, y * height, width, height)
cr.fill()
# increase position
x += 1
if x >= self.BARS_IN_ROW:
x = 0
y += 1
def resizeRequest(self):
"""Calculate a size for window"""
self.rows = len(self.colors)/self.BARS_IN_ROW
if len(self.colors) % self.BARS_IN_ROW != 0:
self.rows += 1
width = self.BAR_SIZE[0] * self.BARS_IN_ROW
height = self.BAR_SIZE[1] * self.rows
self.set_size_request(width, height)
def update(self):
"Redraw window"
event = gtk.gdk.Event(gtk.gdk.EXPOSE)
self.emit("expose-event", event)
def addColor(self, color):
"""Add a single color"""
self.colors.append( gtk.gdk.color_parse(color) )
self.resizeRequest()
self.update()
def resetColors(self):
"""Remove any added color"""
self.colors = self.colors[:self.originalColors]
self.resizeRequest()
self.update()
def changeGrayColors(self):
self.grays = not self.grays
self.update()
class App(gtk.Window):
def __init__(self, tagFile):
super(App, self).__init__()
self.set_title("Generating colors")
self.set_position(gtk.WIN_POS_CENTER)
self.connect("destroy", gtk.main_quit)
vbox = gtk.VBox(False, 2)
self.colors = self.getColors(tagFile)
self.colorWidget = ColorWidget(self.colors)
vbox.pack_start(self.colorWidget)
hbox = gtk.HBox(False, 2)
btn = gtk.Button("Generate color")
btn.connect("pressed", self.generateColor)
hbox.pack_start(btn)
btn = gtk.Button("To gray grades")
btn.connect("pressed", self.changeGrayColors)
self.grayColors = False
hbox.pack_start(btn)
self.revertBtn = gtk.Button("Revert changes")
self.revertBtn.connect("pressed", self.reloadColors)
self.revertBtn.set_sensitive(False)
hbox.pack_start(self.revertBtn)
vbox.pack_start(hbox)
self.add(vbox)
def run(self):
self.show_all()
gtk.main()
def getColors(self, tagFile):
"""Read colors from tag file"""
path = os.path.expanduser(tagFile)
root = ElementTree(file=path)
tags = root.findall('tag')
return [tag.get('color') for tag in tags if tag.get('color')]
def generateColor(self, widget):
"""Generate a new color"""
color = generateColor(self.colors)
self.colorWidget.addColor(color)
# Allow revert button
self.revertBtn.set_sensitive(True)
def reloadColors(self, widget):
"""Revert original colors"""
self.colorWidget.resetColors()
# Disable revert
self.revertBtn.set_sensitive(False)
# Shrink window to minimum size
self.resize(1, 1)
def changeGrayColors(self, widget):
if self.grayColors:
widget.set_label("To gray grades")
self.grayColors = False
else:
widget.set_label("To colors")
self.grayColors = True
self.colorWidget.changeGrayColors()
if __name__ == "__main__":
app = App("~/.local/share/gtg/tags.xml")
if len(sys.argv) >= 2:
print generateColor(app.colors)
else:
app.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment