color_extract 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fcdf8c9b4f5cae0c0df68f6253ac81af6435457a
4
+ data.tar.gz: 9ff5cc7c5c43e25a1183a440e18e7bf8cd2c27d1
5
+ SHA512:
6
+ metadata.gz: 79583d8b9e76d7f89ff0abd2f8a4b7646d72d807337516e7b0f2480ec8cee6b926d07e6eb30ae858cd0b2513c407678e31aa44677709549604acd77cbe581434
7
+ data.tar.gz: 4199a9b1d150627ac1b7a9b68cee415f46364cfd07e231faf8423c21602e97e0abd38ebe9ddb36f7652af923cdfab2ed5adc6fd9a7dadc6a7f93dec789b4648a
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in color_extract.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 qhwa
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.
data/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # ColorExtract
2
+
3
+ This gem extract important colors from an image.
4
+
5
+ on construction
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'color_extract/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "color_extract"
8
+ spec.version = ColorExtract::VERSION
9
+ spec.authors = ["qhwa"]
10
+ spec.email = ["qhwa@163.com"]
11
+ spec.summary = %q{extract color information from images}
12
+ spec.description = %q{extract color information from images}
13
+ spec.homepage = "https://github.com/qhwa/color_extract"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "colorscore", "~> 0.0.4"
22
+
23
+ spec.add_development_dependency "bundler", "~> 1.5"
24
+ spec.add_development_dependency "rake"
25
+ end
@@ -0,0 +1,18 @@
1
+ $:.unshift File.expand_path( '../../lib', __FILE__ )
2
+ require 'color_extract'
3
+
4
+ file = ARGV[0]
5
+ if file
6
+ puts "File: #{file}"
7
+ ColorExtract::Analytics.new( file ).valuable_colors.each do |per, color|
8
+ print " - %#.2f%% %s %s" % [per*100, color.html, color.css_hsl]
9
+ print "\n"
10
+ end
11
+
12
+ puts "palette:"
13
+ ColorExtract::Palette.new( file ).palette.each do |name, color|
14
+ next unless color
15
+ print " - %s : %s %s" % [ name.to_s.ljust(6), color.html, color.css_hsl ]
16
+ print "\n"
17
+ end
18
+ end
@@ -0,0 +1,178 @@
1
+ require 'colorscore'
2
+
3
+ module ColorExtract
4
+
5
+ MAX_VISIBLE_COLORS = 128
6
+
7
+ # Public: 分析图片的色彩信息,相似的颜色会合并在一起
8
+ #
9
+ # Example:
10
+ #
11
+ # img = "http://distilleryimage2...jpg"
12
+ # colors = ColorExtract::Analytics.new( img ).valuable_colors
13
+ # colors.each do |percent, color|
14
+ # puts "#{color.html} : #{percent}"
15
+ # end
16
+ class Analytics
17
+
18
+ include ColorUtil
19
+
20
+ attr_reader :merge_factor
21
+
22
+ def initialize( img )
23
+ @img = img
24
+ end
25
+
26
+ # Public: 获取颜色数组
27
+ #
28
+ # - merge_factor: 颜色合并系数,数字越大,相似的颜色越容易被合并在一起
29
+ #
30
+ # Returns 颜色数组,数组的每个元素都是 [percent, color] 结构
31
+ def valuable_colors( merge_factor: 5 )
32
+ @merge_factor = merge_factor
33
+ @colors ||= calc_valuable_colors
34
+ end
35
+
36
+ private
37
+
38
+ def calc_valuable_colors
39
+ @colors = @raw_colors = visible_colors
40
+
41
+ # 黑白灰是不具有色相的颜色,可以和任何色相的颜色搭配
42
+ # 所以不是我们关心的颜色
43
+ remove_gray_colors
44
+
45
+ # 去掉灰色之后重新计算一下百分比,这样后期就不会有
46
+ # 太多比例特别少的颜色,防止色彩丢失过多
47
+ update_percents
48
+
49
+ # 视觉上相近的颜色都合并成一种进行统计
50
+ # 这样得到的颜色比例会更加精确
51
+ merge_similar_colors
52
+
53
+ # 数量太少的颜色很有可能是主色的过渡
54
+ # 可以去掉和主色同色系的低比例色彩
55
+ remove_few_colors
56
+
57
+ return @colors
58
+ end
59
+
60
+ public
61
+
62
+ # Public: 获取可见的颜色,这里的颜色是没有经过相似合并的
63
+ #
64
+ # Returns 可见颜色数组,数组每个元素都是 [percent, color] 结构
65
+ def visible_colors
66
+ Colorscore::Histogram.new( @img, MAX_VISIBLE_COLORS).scores
67
+ end
68
+
69
+ private
70
+
71
+ def remove_gray_colors
72
+ @colors.reject! do |per, color|
73
+ hsl = color.to_hsl
74
+ # 灰色系颜色
75
+ l, a, b = *rgb2lab(color.to_rgb)
76
+ hsl.s < 0.1 or
77
+ # 接近白色
78
+ l > 83 or
79
+ # 接近黑色
80
+ l < 25
81
+ end
82
+ end
83
+
84
+ def update_percents
85
+ total = @raw_colors.reduce(0) {|sum, info| sum + info[0]}
86
+ @colors.each do |info|
87
+ per, c = *info
88
+ info[0] = per / total
89
+ end
90
+ end
91
+
92
+ # TODO: 重构这个函数
93
+ # 这里应该可以逻辑更加简单一些的
94
+ def merge_similar_colors
95
+
96
+ @colors.each do |info|
97
+ per, c = *info
98
+ info[1] = pure( dither( c ), s: nil, l:nil )
99
+ end
100
+
101
+ auto_link_colors!
102
+
103
+ new_colors = {}
104
+ @colors.each do |per, color|
105
+ link_to = parent_color(color)
106
+ if link_to
107
+ new_colors[link_to] ||= 0
108
+ new_colors[link_to] += per
109
+ else
110
+ new_colors[color.html] = per
111
+ end
112
+ end
113
+
114
+ @colors = new_colors.map do |color_html, per|
115
+ [per, Color::RGB.from_html(color_html)]
116
+ end
117
+ end
118
+
119
+ def auto_link_colors!
120
+ @merge_link = {}
121
+ colors = @colors.sort_by {|per, c| c.to_hsl.h }
122
+ len = colors.size - 1
123
+
124
+ 0.upto(len) do |i|
125
+ per, color, lab = *colors[i]
126
+ hsl = color.to_hsl
127
+
128
+ (i+1).upto(len) do |j|
129
+ per2, color2, lab2 = *colors[j]
130
+
131
+ if should_merge?(color, color2)
132
+ # 相近的颜色,合并到面积更大的那种颜色
133
+ # 这里尝试过另外的策略,比如合并到更鲜艳
134
+ # 的那种颜色,但是效果不是很好
135
+ if per >= per2
136
+ @merge_link[color.html] = parent_color(color2)
137
+ else
138
+ @merge_link[color2.html] = parent_color(color)
139
+ end
140
+ end
141
+ end
142
+ end
143
+ end
144
+
145
+ def should_merge?( color1, color2 )
146
+ hue_similarity( color1, color2 ) <= 20 && similarity( color1, color2, ignore_lightness: true ) < @merge_factor
147
+ end
148
+
149
+ def parent_color color
150
+ parent = @merge_link[color.html]
151
+ if parent && parent != color.html
152
+ parent_color( Color::RGB.from_html(parent) )
153
+ else
154
+ color.html
155
+ end
156
+ end
157
+
158
+ def remove_few_colors
159
+ sorted_colors = @colors.sort_by {|per,c| -per}
160
+ if sorted_colors.size > 5
161
+ sorted_colors.reject! {|per, c| per < 0.0005 }
162
+ end
163
+ common_colors = sorted_colors
164
+ little_colors = sorted_colors.select {|per, c| per < 0.05 }
165
+
166
+ little_colors.select! do |per, c|
167
+ common_colors.any? do |common_per, common_color|
168
+ common_per > per && hue_similarity( c, common_color ) <= 10
169
+ end
170
+ end
171
+
172
+ @colors = sorted_colors - little_colors
173
+ end
174
+
175
+ end
176
+
177
+ end
178
+
@@ -0,0 +1,131 @@
1
+ module ColorExtract
2
+
3
+ module ColorUtil
4
+
5
+ # Corresponds roughly to RGB brighter/darker
6
+ K = 18
7
+
8
+ # D65 standard referent
9
+ X = 0.950470
10
+ Y = 1
11
+ Z = 1.088830
12
+
13
+ # 使用 CIE76 公式计算颜色的相似程度
14
+ # 参考:
15
+ # - [CIELAB](http://en.wikipedia.org/wiki/CIELAB)
16
+ # - [Color Difference](http://en.wikipedia.org/wiki/Color_difference)
17
+ def similarity( color1, color2, ignore_lightness: false )
18
+ l1, a1, b1 = *rgb2lab(color1.to_rgb)
19
+ l2, a2, b2 = *rgb2lab(color2.to_rgb)
20
+ Math.sqrt( (ignore_lightness ? 0 : (l1-l2)**2) + (a1-a2)**2 + (b1-b2)**2 )
21
+ end
22
+
23
+ # Public: 判断两种颜色的色系相似程度
24
+ # 在色盘上越接近,返回值越小
25
+ #
26
+ # Returns 色相距离,0-180之间的角度值
27
+ def hue_similarity( color1, color2 )
28
+ deg1 = color1.to_hsl.h
29
+ deg2 = color2.to_hsl.h
30
+ deg1 += 1 if deg1 < 0
31
+ deg2 += 1 if deg2 < 0
32
+ delta = (deg1 - deg2).abs
33
+ delta = 1 - delta if delta > 0.5
34
+ delta * 360
35
+ end
36
+
37
+ # 来自 github 上的开源项目 chroma
38
+ # https://github.com/gka/chroma.js/blob/master/src/conversions/rgb2lab.coffee
39
+ #
40
+ # color - RGB颜色
41
+ #
42
+ # Returns [l*, a*, b*] 值。
43
+ # 亮度(l*)的范围是(0-100)
44
+ def rgb2lab(color)
45
+ r, g, b = color.r * 255, color.g * 255, color.b * 255
46
+ r = rgb_xyz r
47
+ g = rgb_xyz g
48
+ b = rgb_xyz b
49
+ x = xyz_lab (0.4124564 * r + 0.3575761 * g + 0.1804375 * b) / X
50
+ y = xyz_lab (0.2126729 * r + 0.7151522 * g + 0.0721750 * b) / Y
51
+ z = xyz_lab (0.0193339 * r + 0.1191920 * g + 0.9503041 * b) / Z
52
+ [116 * y - 16, 500 * (x - y), 200 * (y - z)]
53
+ end
54
+
55
+ def rgb_xyz (r)
56
+ if (r /= 255) <= 0.04045 then r / 12.92 else ((r + 0.055) / 1.055) ** 2.4 end
57
+ end
58
+
59
+ def xyz_lab (x)
60
+ if x > 0.008856 then x ** (1.0/3) else 7.787037 * x + 4 / 29 end
61
+ end
62
+
63
+ # Public: 根据背景色,计算适用于显示其上的文字的颜色
64
+ def readable_textcolor( bg: nil, accent: nil, lock_accent: false)
65
+ l1, a1, b1 = *rgb2lab(bg)
66
+ if accent
67
+ l2, a2, b2 = *rgb2lab(accent)
68
+ return accent if (l1 - l2).abs > 255 * 0.8
69
+ end
70
+
71
+ # TODO: ajust accent unless lock_accent
72
+ # 白色会显得品质高档,因此尽量使用白色
73
+ if l1 < 75
74
+ Color::RGB.from_html( '#FFFFFF' )
75
+ else
76
+ bg.to_hsl.tap { |c| c.l = 0.1 }.to_rgb
77
+ end
78
+ end
79
+
80
+ def pure( color, s: 1, l: 1 )
81
+ color.to_hsl.tap do |c|
82
+ if s
83
+ c.s = s
84
+ else
85
+ c.s += (1 - c.s) * 0.382
86
+ end
87
+ c.l = l if l
88
+ end.to_rgb
89
+ end
90
+
91
+ def dither( color )
92
+ color.to_hsl.tap do |c|
93
+ if c.s > 0.8
94
+ c.s -= (c.s) * 0.3
95
+ c.l -= 0.1
96
+ else
97
+ c.s += (1-c.s) * 0.5
98
+ end
99
+ end
100
+ end
101
+
102
+ def reverse_color( color )
103
+ color.to_hsl.tap do |c|
104
+ # 色盘旋转60度
105
+ h = c.h + 1.0/6
106
+ h -= 1 if h > 1
107
+ c.h = h
108
+ end.to_rgb
109
+ end
110
+
111
+ def darken( hsl_color, percent )
112
+ hsl_color.tap { |c| darken!( c, percent ) }
113
+ end
114
+
115
+ def darken!( hsl_color, percent )
116
+ l = hsl_color.l
117
+ hsl_color.l -= (1-l) * percent
118
+ end
119
+
120
+ def lighten( hsl_color, percent )
121
+ hsl_color.tap { |c| lighten!( c, percent ) }
122
+ end
123
+
124
+ def lighten!( hsl_color, percent )
125
+ l = hsl_color.l
126
+ hsl_color.l += l * percent
127
+ end
128
+
129
+ end
130
+
131
+ end
@@ -0,0 +1,188 @@
1
+ module ColorExtract
2
+
3
+ class Palette
4
+
5
+ include ColorUtil
6
+
7
+ class << self
8
+ def from_colors( colors )
9
+ new.tap do |palette|
10
+ palette.raw_colors = colors.to_a
11
+ end
12
+ end
13
+ end
14
+
15
+ attr_accessor :raw_colors, :main_color, :max_pri_brightness
16
+
17
+ def initialize( file = nil )
18
+ @analytics = Analytics.new( file ) if file
19
+ end
20
+
21
+ # 目前只生成一种配色方案
22
+ def palette( accent_seed: nil )
23
+ palettes( count: 1, accent_seed: accent_seed ).first
24
+ end
25
+
26
+ def palettes( opts={} )
27
+ @raw_colors ||= @analytics.valuable_colors.map {|per, c| c }
28
+ @palettes ||= gen_palettes( opts )
29
+ end
30
+
31
+ private
32
+
33
+ # 目前采用最简单
34
+ def gen_palettes( count: 1, accent_seed: nil, max_pri_brightness: 1 )
35
+ count = 1 if accent_seed
36
+ @max_pri_brightness = max_pri_brightness
37
+ @main_color = most_possible_main_color
38
+ @accent_colors = []
39
+
40
+ palettes = count.times.map do |i|
41
+ gen_palette( accent_seed: accent_seed, fewest_index: i )
42
+ end.compact.sort_by do |pal|
43
+ pal[:primary].to_hsl.h
44
+ end
45
+
46
+ if palettes.size < count
47
+
48
+ if palettes.empty?
49
+ return preset_palettes( count: count )
50
+ end
51
+
52
+ last_primary_color = palettes.last[:primary].to_hsl
53
+ main_color = palettes.last[:back].to_hsl
54
+ puts last_primary_color.html
55
+ (count - palettes.size ).times do |i|
56
+ if i.even?
57
+ color = last_primary_color.dup.tap do |c|
58
+ h = c.h
59
+ h += ((i+1)/2.0).ceil / 10.0
60
+ h += 1 if h < 0
61
+ c.h = h
62
+ c.l = 0.33
63
+ end.to_rgb
64
+ else
65
+ color = main_color.dup.tap do |c|
66
+ h = c.h
67
+ h -= ((i+1)/2.0).ceil / 10.0
68
+ h += 1 if h < 0
69
+ c.h = h
70
+ c.l = 0.33
71
+ end.to_rgb
72
+ end
73
+ next if already_have_similar_accent_color?( color )
74
+ palettes << gen_palette( accent_seed: color )
75
+ end
76
+ end
77
+
78
+ palettes.compact
79
+ end
80
+
81
+ def preset_palettes( count: 1 )
82
+ 0.upto(count).map do |i|
83
+ accent = Color::HSL.from_fraction( i*(1.0 /(count+1)), 0.95, 0.4 )
84
+ main = Color::RGB.from_html( '#ffffff' )
85
+ {
86
+ :primary => accent.to_rgb,
87
+ :back => main,
88
+ :"pri-dark" => darken( accent, 0.2 ).to_rgb,
89
+ :"pri-light" => lighten( accent, 0.2 ).to_rgb,
90
+ :"text" => readable_textcolor( bg: accent.to_rgb, accent: main.to_rgb )
91
+ }
92
+ end
93
+ end
94
+
95
+ def most_possible_main_color
96
+ raw_colors.size > 0 ? raw_colors.first : Color::RGB.from_html( '#CCCCCC' )
97
+ end
98
+
99
+ # Private: 生成配色方案
100
+ #
101
+ # accent_seed: 指定的 primary 颜色
102
+ # fewest_index: 指定倒数第几个最少的颜色
103
+ # 0 - 最少的颜色;
104
+ # 1 - 倒数第二少的颜色;
105
+ # 以此类推
106
+ #
107
+ # Returns 一种配色方案
108
+ def gen_palette( accent_seed: nil, fewest_index: 0 )
109
+ accent_color = accent_seed || most_possible_accent_color( fewest_index )
110
+ if !accent_color || already_have_similar_accent_color?( accent_color )
111
+ return nil
112
+ else
113
+ @accent_colors << accent_color
114
+ end
115
+
116
+ if accent_color
117
+ light, dark = most_possible_around_colors( accent_color )
118
+ text_color = readable_textcolor bg: accent_color, accent: main_color
119
+ {
120
+ primary: accent_color,
121
+ :'pri-light' => light,
122
+ :'pri-dark' => dark,
123
+ back: @main_color,
124
+ text: text_color
125
+ }
126
+ end
127
+ end
128
+
129
+ def most_possible_accent_color( fewest_index=0, &block )
130
+
131
+ color = if raw_colors.size > fewest_index + 1
132
+ # 除去最多的一种颜色
133
+ # 因为最多的颜色是作为 back
134
+ raw_colors.reverse[0..-2].compact.sort_by do |c|
135
+ hue_simi = hue_similarity(c, main_color)
136
+ simi = hue_simi > 60 ? -0.5*hue_simi + 120 : 1.5*hue_simi
137
+ l,a,b = *rgb2lab(c)
138
+ sat = c.to_hsl.s
139
+ # 按和主要颜色的差异系数由小到大排
140
+ # 饱和度越高、亮度越低的越有可能成为主色
141
+ # simi: 0-90; l: 0-100; sat: 0-1
142
+ simi * 2 + sat * 10 - l * 7.01
143
+ end.reverse[fewest_index]
144
+ end
145
+
146
+ if max_pri_brightness && color
147
+ color.to_hsl.tap do |c|
148
+ c.l = max_pri_brightness if c.l > max_pri_brightness
149
+ end.to_rgb
150
+ else
151
+ color
152
+ end
153
+ end
154
+
155
+ def already_have_similar_accent_color?( color )
156
+ @accent_colors.any? do |c|
157
+ similarity( c, color, ignore_lightness: false ) < 20
158
+ end
159
+ end
160
+
161
+ def most_possible_around_colors( accent_color )
162
+ sub_color1 = nil
163
+ sub_color2 = nil
164
+
165
+ if raw_colors.size > 4
166
+ raw_colors[1..-1].each do |c|
167
+ if hue_similarity(c, accent_color ) < 30
168
+ if sub_color1.nil?
169
+ sub_color1 = c.to_hsl.tap do |c|
170
+ c.l = accent_color.to_hsl.l + 0.2
171
+ end.to_rgb
172
+ else
173
+ sub_color2 = c.to_hsl.tap do |c|
174
+ c.l = accent_color.to_hsl.l - 0.2
175
+ end.to_rgb
176
+ end
177
+ end
178
+ end
179
+ end
180
+
181
+ sub_color1 ||= accent_color.to_hsl.tap {|c| lighten!(c, 0.2) }.to_rgb
182
+ sub_color2 ||= accent_color.to_hsl.tap {|c| darken!(c, 0.2) }.to_rgb
183
+ [sub_color1, sub_color2]
184
+ end
185
+
186
+ end
187
+
188
+ end
@@ -0,0 +1,3 @@
1
+ module ColorExtract
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ require "color_extract/version"
2
+ require 'color_extract/color_util'
3
+ require "color_extract/analytics"
4
+ require 'color_extract/palette'
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: color_extract
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - qhwa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-04-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: colorscore
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.0.4
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.0.4
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: extract color information from images
56
+ email:
57
+ - qhwa@163.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - LICENSE.txt
65
+ - README.md
66
+ - Rakefile
67
+ - color_extract.gemspec
68
+ - example/extract.rb
69
+ - lib/color_extract.rb
70
+ - lib/color_extract/analytics.rb
71
+ - lib/color_extract/color_util.rb
72
+ - lib/color_extract/palette.rb
73
+ - lib/color_extract/version.rb
74
+ homepage: https://github.com/qhwa/color_extract
75
+ licenses:
76
+ - MIT
77
+ metadata: {}
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '0'
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - ">="
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 2.2.2
95
+ signing_key:
96
+ specification_version: 4
97
+ summary: extract color information from images
98
+ test_files: []