Skip to content

Instantly share code, notes, and snippets.

@mattsears
Created September 19, 2011 13:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mattsears/1226524 to your computer and use it in GitHub Desktop.
Save mattsears/1226524 to your computer and use it in GitHub Desktop.
Colr: A color selector tool

Colr.rb

Colr selects colors based on hue calculations. It knows nothing about the image before initialization and works with any valid HTML color: red, green, aqua, brown, etc.

Colr allows you to adjust the tolerance and hue settings so you can select colors from any image!

Example:

@colr = Colr.new('input.png')
@colr.select(:red).save("red.png")

# To select all the colors:

Colr.new('input.png').select(:yellow, 40, -40).save("yellow.png")
Colr.new('input.png').select(:red).save("red.png")
Colr.new('input.png').select(:green, 30, -60).save("green.png")
Colr.new('input.png').select(:blue, 20, -50).save("blue.png")
Colr.new('input.png').select(:violet, 20, -70).save("violet.png")
require 'chunky_png'
class Colr
include ChunkyPNG::Color
def initialize(png)
@input = ChunkyPNG::Image.from_file(png)
end
# Converts each pixel of the image to grayscale except the given color. You
# can use the tolerance and degrees (hues) to tune Colr to match any image!
#
# Example:
# @colr.select(:red) #=> ChunkyPNG::Image
#
# Returns the resulting image
def select(color, tolerance = 10, degrees = 0)
hues = swatch(color, tolerance, degrees)
@input.pixels.map! { |c| hues.include?( hue(c) ) ? c : to_grayscale(c) }
@input
end
# Calculates a hue of the given color
# Algorithm from http://en.wikipedia.org/wiki/HSL_and_HSV
#
# Example:
# @colr.hue(0xff000000) #=> 0
#
# Returns the resulting integer value of the hue
def hue(color)
r,g,b = to_truecolor_bytes(color)
min, max = [r,g,b].min, [r,g,b].max
d = max - min
h = case max
when min; 0
when r; 60 * (g-b)/d
when g; 60 * (b-r)/d + 120
when b; 60 * (r-g)/d + 240
end % 360
end
# Calculates a range to hues given the color, tolerance, and
#
# Example:
# @colr.swatch(:red) #=> 0..10
#
# Returns a new Range of hues
def swatch(color, tolerance, degrees)
h = hue(PREDEFINED_COLORS[color.to_sym]) + degrees
Range.new(h, h+tolerance)
end
end
require 'minitest/autorun'
require File.join(File.dirname(__FILE__), 'colr.rb')
describe Colr do
before do
@colr = Colr.new('input.png')
end
it 'calculates hues for html colors' do
@colr.hue(0xff000000).must_equal 0
end
it "returns a range for positive values" do
@colr.swatch(:red, 10, 0).must_equal 0..10
end
it 'returns values for negative degrees' do
@colr.swatch(:green, 30, -60).must_equal 60..90
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment