kolors 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ /pkg/
2
+ /.DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kolors.gemspec
4
+ gemspec
@@ -0,0 +1,42 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ kolors (0.0.1)
5
+ ai4r
6
+ cocaine
7
+ oily_png
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ activesupport (3.2.11)
13
+ i18n (~> 0.6)
14
+ multi_json (~> 1.0)
15
+ ai4r (1.12)
16
+ chunky_png (1.2.7)
17
+ climate_control (0.0.3)
18
+ activesupport (>= 3.0)
19
+ cocaine (0.5.1)
20
+ climate_control (>= 0.0.3, < 1.0)
21
+ diff-lcs (1.1.3)
22
+ i18n (0.6.1)
23
+ multi_json (1.5.0)
24
+ oily_png (1.0.3)
25
+ chunky_png (~> 1.2.1)
26
+ rake (10.0.3)
27
+ rspec (2.12.0)
28
+ rspec-core (~> 2.12.0)
29
+ rspec-expectations (~> 2.12.0)
30
+ rspec-mocks (~> 2.12.0)
31
+ rspec-core (2.12.2)
32
+ rspec-expectations (2.12.1)
33
+ diff-lcs (~> 1.1.3)
34
+ rspec-mocks (2.12.2)
35
+
36
+ PLATFORMS
37
+ ruby
38
+
39
+ DEPENDENCIES
40
+ kolors!
41
+ rake
42
+ rspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Eric Larson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,48 @@
1
+ # Kolors
2
+
3
+ Uses KMeans clustering and the L*A*B* colorspace to extract "approximate human vision" dominant colors from an image. Optionally, map those dominant colors into preferred "color bins" for a search index facet-by-color solution.
4
+
5
+ LARGELY based off the neat work of the [Miro gem](https://github.com/jonbuda/miro). If you want faster, RGB-based dominant color extraction, use Miro.
6
+
7
+ ## Dependencies
8
+
9
+ Requires Imagemagick. On OSX use homebrew to install: brew install imagemagick
10
+
11
+ ## Installation
12
+
13
+ $ gem install kolors
14
+
15
+ ## Usage
16
+
17
+ ```ruby
18
+ require 'kolors'
19
+
20
+ # Use path to a local image or URL for remote image
21
+ kolors = Kolors::DominantColors.new('../colors/images/QFZMF57HPHVGJ8Z_thumb.png')
22
+
23
+ # Return the dominant colors in LAB
24
+ kolors.to_lab
25
+ => [[52.406, -18.186, 27.618], [88.523, -10.393, 16.203], [64.944, -16.181, 24.419], [28.486, -16.665, 22.73]]
26
+
27
+ # Return the mapped color bins and color percentage for facet-by-color
28
+ kolors.to_facets
29
+ => [{"Moss"=>50.05952380952381}, {"Mercury"=>9.880952380952381}, {"Aluminum"=>19.186507936507937}, {"Iron"=>20.873015873015873}]
30
+ ```
31
+
32
+ ## TODOS
33
+
34
+ 1. LAB to RGB conversion
35
+ 2. Simplify configuration of "color bins" for facet-by-color mapping
36
+ 3. Tests
37
+
38
+ ## Thanks
39
+
40
+ Special thanks to my buddy [Nate Vack](https://github.com/njvack) for help getting this off of the ground.
41
+
42
+ ## Contributing
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
@@ -0,0 +1,31 @@
1
+ h1. Colors
2
+
3
+ A neat facet-by-color script (proof-of-concept).
4
+
5
+ * Uses "Miro":https://github.com/jonbuda/miro to pull the dominant colors from an image.
6
+ * Uses "Euclidian distance":http://en.wikipedia.org/wiki/Euclidean_distance to map dominant colors into pre-defined facet color bins
7
+
8
+ h3. To use
9
+
10
+ Install ImageMagick, via Homebrew (OS X)
11
+ Install Solr 4.0.0
12
+
13
+ Install these fine gems:
14
+ require 'mechanize' # Crawl a UW Digital Collection for data, images
15
+ require 'chunky_png' # Pure Ruby image manipulation
16
+ require 'miro' # Detect dominant image colors
17
+ require 'rsolr' # Solr
18
+ require 'fileutils' # Save files, delete files, etc.
19
+ require 'awesome_print'
20
+ require 'active_support/core_ext/string'
21
+
22
+ Start Solr:
23
+ $> cd /apache-solr-4.0.0/example/
24
+ $> java -jar start.jar
25
+
26
+ Run the script:
27
+ $> ./colors.rb
28
+
29
+ h3. Todo
30
+
31
+ This is just play for now, should make a *real* tool of this someday...
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kolors/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "kolors"
8
+ gem.version = Kolors::VERSION
9
+ gem.authors = ["Eric Larson"]
10
+ gem.email = ["ewlarson@gmail.com"]
11
+ gem.description = %q{Uses KMeans clustering and the L*A*B* colorspace to extract "approximate human vision" dominant colors from an image. Optionally, use Euclidean Distance to map those dominant colors into preferred "color bins" for a search index facet-by-color solution.}
12
+ gem.summary = %q{Uses KMeans clustering and the L*A*B* colorspace to extract "approximate human vision" dominant colors from an image.}
13
+ gem.homepage = "https://github.com/ewlarson/kolors"
14
+
15
+ gem.requirements = 'ImageMagick'
16
+ gem.add_dependency 'ai4r'
17
+ gem.add_dependency 'cocaine'
18
+ gem.add_dependency 'oily_png'
19
+
20
+ gem.add_development_dependency 'rake'
21
+ gem.add_development_dependency 'rspec'
22
+
23
+ gem.files = `git ls-files`.split($/)
24
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
25
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
26
+ gem.require_paths = ["lib"]
27
+ end
@@ -0,0 +1,36 @@
1
+ require 'kolors/version'
2
+ require 'oily_png' # Fast ChunkyPNG
3
+ require 'ai4r' # KMeans Clustering
4
+ require 'cocaine'
5
+ require 'open-uri'
6
+ require "tempfile"
7
+
8
+ require 'kolors/rgb'
9
+ require 'kolors/dominant_colors'
10
+
11
+ # Define a list of key LAB colors
12
+ def key_colors
13
+ # OSX Crayons in LAB
14
+ { [82.046, 0.004, -0.009] => 'Silver', [21.247, 0.002, -0.003] => 'Tungsten', [72.944, 0.004, -0.008] => 'Magnesium', [32.319, 0.002, -0.004] => 'Iron', [63.223, 0.004, -0.007] => 'Aluminum', [43.192, 0.003, -0.005] => 'Steel', [53.585, 0.003, -0.006] => 'Nickel', [53.193, 0.003, -0.006] => 'Tin', [25.531, 48.055, 38.060] => 'Cayenne', [51.868, -12.931, 56.677] => 'Asparagus', [46.229, -51.700, 49.898] => 'Clover', [48.256, -28.842, -8.481] => 'Teal', [12.975, 47.508, -64.704] => 'Midnight', [29.782, 58.940, -36.498] => 'Plum', [34.510, 23.976, 44.820] => 'Mocha', [47.660, -39.672, 51.639] => 'Fern', [46.722, -45.498, 26.354] => 'Moss', [27.367, 9.122, -41.018] => 'Ocean', [18.577, 50.163, -55.230] => 'Eggplant', [26.619, 50.976, 0.503] => 'Maroon', [53.233, 80.109, 67.220] => 'Maraschino', [97.138, -21.556, 94.482] => 'Lemon', [87.737, -86.185, 83.181] => 'Spring', [91.117, -48.080, -14.138] => 'Turquoise', [32.303, 79.197, -107.864] => 'Blueberry', [60.320, 98.254, -60.843] => 'Magenta', [67.050, 42.832, 74.026] => 'Tangerine', [89.910, -67.789, 85.826] => 'Lime', [88.485, -76.749, 46.572] => 'Sea Foam', [54.719, 18.790, -70.925] => 'Aqua', [40.911, 83.182, -93.300] => 'Grape', [54.885, 84.552, 4.066] => 'Strawberry', [63.112, 58.245, 30.548] => 'Salmon', [97.527, -18.441, 70.899] => 'Banana', [89.535, -69.168, 59.807] => 'Flora', [92.382, -39.947, -12.114] => 'Ice', [51.322, 43.621, -76.298] => 'Orchid', [68.008, 76.237, -48.630] => 'Bubblegum', [8.757, 0.001, -0.002] => 'Lead', [91.293, 0.005, -0.010] => 'Mercury', [84.692, 7.020, 56.682] => 'Cantaloupe', [94.019, -38.132, 66.065] => 'Honeydew', [91.100, -52.338, 12.396] => 'Spindrift', [78.011, -15.169, -33.928] => 'Sky', [61.273, 64.277, -59.740] => 'Lavender', [67.377, 65.168, -23.019] => "Carnation", [0.000, 0.000, 0.000] => "Licorice", [100.000, 0.005, -0.010] => 'Snow' }
15
+
16
+ # Crayola Crayons - 16ct
17
+ # { [0.0, 0.0, 0.0] => 'Black', [47.909, 35.209, -82.012] => 'Blue', [56.951, -21.113, -26.486] => 'Blue Green', [42.436, 30.554, -49.715] => 'Blue Violet', [47.76, 32.728, 31.38] => 'Brown', [77.727, 37.465, -4.165] => 'Pink', [59.159, -50.156, 20.795] => 'Green', [62.726, 54.468, 64.68] => 'Orange', [50.193, 76.218, 36.382] => 'Red', [57.137, 70.48, 50.904] => 'Red Orange', [45.117, 60.767, -14.844] => 'Red Violet', [45.101, 31.746, -33.512] => 'Violet (Purple)', [100.0, 0.005, -0.01] => 'White', [91.412, -8.107, 59.726] => 'Yellow', [85.567, -25.05, 47.104] => 'Yellow Green', [77.236, 20.651, 64.455] => 'Yellow Orange' }
18
+ end
19
+
20
+ # Euclidean distance
21
+ # - Take a dominant color from an image, return nearest key color
22
+ def dist(p1, p2)
23
+ (0...p1.length).map {|i| (p1[i]-p2[i])**2}.inject(0) {|sum, i| sum+i}**0.5
24
+ end
25
+
26
+ module Kolors
27
+ class << self
28
+ def options
29
+ @options ||= {
30
+ :image_magick_path => '/usr/local/bin/convert',
31
+ :resolution => '100x100',
32
+ :color_count => 4
33
+ }
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,93 @@
1
+ module Kolors
2
+ class DominantColors
3
+ attr_accessor :src_image_path
4
+
5
+ def initialize(src_image_path)
6
+ @src_image_path = src_image_path
7
+ end
8
+
9
+ def to_facets
10
+ # Map each centroid to key_colors
11
+ facets = to_lab.each_with_index.collect do |color,index|
12
+ { key_colors[key_colors.keys.sort_by {|c| dist(color, c) }.first] => kmeans_result.clusters[index].data_items.size}
13
+ end
14
+ percentize(group_hashes_sum_values(facets))
15
+ end
16
+
17
+ def to_lab
18
+ kmeans_result.centroids.collect{|r,g,b| Kolors::Rgb.new(r,g,b).to_lab}
19
+ end
20
+
21
+ def kmeans_result
22
+ @kmeans_result ||= extract_colors_from_image
23
+ end
24
+
25
+ private
26
+
27
+ def percentize(hash)
28
+ hash.collect{|color, count| {color => ((count.to_f / @colors.size.to_f)*100)}}
29
+ end
30
+
31
+ def group_hashes_sum_values(array)
32
+ array.inject{|color, count| color.merge( count ){|k, old_v, new_v| old_v + new_v}}
33
+ end
34
+
35
+ def extract_colors_from_image
36
+ create_thumb_crop_and_convert_to_png!
37
+ colors = detect_dominant_colors
38
+ cleanup_temporary_files!
39
+ return colors
40
+ end
41
+
42
+ def remote_source_image?
43
+ @src_image_path =~ /^https?:\/\//
44
+ end
45
+
46
+ def create_thumb_crop_and_convert_to_png!
47
+ @source_image = open_source_image
48
+ @downsampled_image = open_downsampled_image
49
+
50
+ Cocaine::CommandLine.new(Kolors.options[:image_magick_path], "':in[0]' -resize :resolution -gravity Center -crop 90x80%+0+0 :out").
51
+ run(:in => File.expand_path(@source_image.path),
52
+ :resolution => Kolors.options[:resolution],
53
+ :out => File.expand_path(@downsampled_image.path))
54
+ end
55
+
56
+ def open_source_image
57
+ if remote_source_image?
58
+ original_extension = URI.parse(@src_image_path).path.split('.').last
59
+
60
+ tempfile = Tempfile.open(["source", ".#{original_extension}"])
61
+ remote_file_data = open(@src_image_path).read
62
+
63
+ tempfile.write(RUBY_VERSION =~ /1.9/ ? remote_file_data.force_encoding("UTF-8") : remote_file_data)
64
+ tempfile.close
65
+ return tempfile
66
+ else
67
+ return File.open(@src_image_path)
68
+ end
69
+ end
70
+
71
+ def open_downsampled_image
72
+ tempfile = Tempfile.open(["downsampled", '.png'])
73
+ tempfile.binmode
74
+ tempfile
75
+ end
76
+
77
+ def detect_dominant_colors
78
+ # Detect dominant colors
79
+ # - Fetches colors from ChunkyPNG directly
80
+ @colors = ChunkyPNG::Image.from_file(File.expand_path(@downsampled_image.path)).pixels.collect {|c| ChunkyPNG::Color.to_truecolor_bytes c }
81
+
82
+ # Kmeans cluster
83
+ data = Ai4r::Data::DataSet.new(:data_items => @colors)
84
+ kmeans = Ai4r::Clusterers::KMeans.new
85
+ result = kmeans.build(data, Kolors.options[:color_count])
86
+ end
87
+
88
+ def cleanup_temporary_files!
89
+ @source_image.close(true) if remote_source_image?
90
+ @downsampled_image.close(true)
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,98 @@
1
+ module Kolors
2
+ class Rgb
3
+ attr_reader :r, :g, :b
4
+ attr_reader :l, :a, :b
5
+
6
+ def initialize(r,g,b)
7
+ @r = r
8
+ @g = g
9
+ @b = b
10
+ end
11
+
12
+ # EasyRGB - RGB to LAB
13
+ # - LAB gives us a perceptually accurate colorspace
14
+ def to_lab
15
+ x,y,z = rgb_to_xyz(@r,@g,@b)
16
+ l,a,b = xyz_to_lab(x,y,z)
17
+ end
18
+
19
+ protected
20
+
21
+ # EasyRGB - RGB to XYZ
22
+ def rgb_to_xyz(r,g,b)
23
+ r = r * 1.0
24
+ g = g * 1.0
25
+ b = b * 1.0
26
+
27
+ var_R = ( r / 255.0 ) #R from 0 to 255
28
+ var_G = ( g / 255.0 ) #G from 0 to 255
29
+ var_B = ( b / 255.0 ) #B from 0 to 255
30
+
31
+ if ( var_R > 0.04045 )
32
+ var_R = ( ( var_R + 0.055 ) / 1.055 ) ** 2.4
33
+ else
34
+ var_R = var_R / 12.92
35
+ end
36
+
37
+ if ( var_G > 0.04045 )
38
+ var_G = ( ( var_G + 0.055 ) / 1.055 ) ** 2.4
39
+ else
40
+ var_G = var_G / 12.92
41
+ end
42
+
43
+ if ( var_B > 0.04045 )
44
+ var_B = ( ( var_B + 0.055 ) / 1.055 ) ** 2.4
45
+ else
46
+ var_B = var_B / 12.92
47
+ end
48
+
49
+ var_R = var_R * 100
50
+ var_G = var_G * 100
51
+ var_B = var_B * 100
52
+
53
+ # Observer. = 2°, Illuminant = D65
54
+ x = var_R * 0.4124 + var_G * 0.3576 + var_B * 0.1805
55
+ y = var_R * 0.2126 + var_G * 0.7152 + var_B * 0.0722
56
+ z = var_R * 0.0193 + var_G * 0.1192 + var_B * 0.9505
57
+
58
+ return [x,y,z]
59
+ end
60
+
61
+ # EasyRGB - XYZ to CIELAB
62
+ def xyz_to_lab(x,y,z)
63
+ var_X = x / 95.047 #ref_X = 95.047 Observer= 2°, Illuminant= D65
64
+ var_Y = y / 100.000 #ref_Y = 100.000
65
+ var_Z = z / 108.883 #ref_Z = 108.883
66
+
67
+ if ( var_X > 0.008856 )
68
+ var_X = var_X ** ( 1.0/3.0 )
69
+ else
70
+ var_X = ( 7.787 * var_X ) + ( 16.0 / 116.0 )
71
+ end
72
+
73
+ if ( var_Y > 0.008856 )
74
+ var_Y = var_Y ** ( 1.0/3.0 )
75
+ else
76
+ var_Y = ( 7.787 * var_Y ) + ( 16.0 / 116.0 )
77
+ end
78
+
79
+ if ( var_Z > 0.008856 )
80
+ var_Z = var_Z ** ( 1.0/3.0 )
81
+ else
82
+ var_Z = ( 7.787 * var_Z ) + ( 16.0 / 116.0 )
83
+ end
84
+
85
+ l = ( 116.0 * var_Y ) - 16.0
86
+ a = 500.0 * ( var_X - var_Y )
87
+ b = 200.0 * ( var_Y - var_Z )
88
+
89
+ return [l.round(3),a.round(3),b.round(3)]
90
+ end
91
+
92
+ # EasyRGB - RGB to LAB
93
+ def rgb_to_lab(r,g,b)
94
+ x,y,z = rgb_to_xyz(r,g,b)
95
+ l,a,b = xyz_to_lab(x,y,z)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,3 @@
1
+ module Kolors
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,143 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kolors
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Larson
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-04 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: ai4r
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: cocaine
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: oily_png
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rake
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: Uses KMeans clustering and the L*A*B* colorspace to extract "approximate
95
+ human vision" dominant colors from an image. Optionally, use Euclidean Distance
96
+ to map those dominant colors into preferred "color bins" for a search index facet-by-color
97
+ solution.
98
+ email:
99
+ - ewlarson@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - .gitignore
105
+ - Gemfile
106
+ - Gemfile.lock
107
+ - LICENSE
108
+ - README.md
109
+ - README.textile
110
+ - Rakefile
111
+ - kolors.gemspec
112
+ - lib/kolors.rb
113
+ - lib/kolors/dominant_colors.rb
114
+ - lib/kolors/rgb.rb
115
+ - lib/kolors/version.rb
116
+ homepage: https://github.com/ewlarson/kolors
117
+ licenses: []
118
+ post_install_message:
119
+ rdoc_options: []
120
+ require_paths:
121
+ - lib
122
+ required_ruby_version: !ruby/object:Gem::Requirement
123
+ none: false
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ requirements:
135
+ - ImageMagick
136
+ rubyforge_project:
137
+ rubygems_version: 1.8.24
138
+ signing_key:
139
+ specification_version: 3
140
+ summary: Uses KMeans clustering and the L*A*B* colorspace to extract "approximate
141
+ human vision" dominant colors from an image.
142
+ test_files: []
143
+ has_rdoc: