color_namer_ruby 0.1.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: eb8445c3407dff549f27e518515249fbe4dc5c3a5de0a7b388bc14968d8118f9
4
+ data.tar.gz: 4f684c4a7fc9e8f01f301c538692252c893de978d0fafca53ac95604357c7759
5
+ SHA512:
6
+ metadata.gz: 3cfc740a65645606ce24fabf1b0fb583ee445953f5cbe64f7cdd1b4e08b0fc51321bb4d7a6156f64e65d90d260cb2a2ef10b89242a3340feab27b063d719baea
7
+ data.tar.gz: c4cf7454c3a41dda0011cd2bf953a1a78503e115a79c507a9b9a91bb80a48620c1436e1724072111e050e9ad367508e5bfedd6793bbd106f63e4a36c7b74e062
data/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # Color Namer Ruby
2
+
3
+ > Give me a color and I'll name it.
4
+
5
+ Color Namer Ruby is an ruby gem package for use in ruby or other projects that provides names for colours based on calculated color distances using the [Delta-E](http://www.colorwiki.com/wiki/Delta_E%3a_The_Color_Difference) color difference technique.
6
+ Given a color in [Hexadecimal, RGA(A), HSL(A), HSV, HSB, or CMYK format](https://github.com/devrieda/color_conversion), it converts the color to the [HSL color space](https://en.wikipedia.org/wiki/HSL_and_HSV) (for now),
7
+ then calculates the color's [Euclidean distance](https://npmjs.org/package/euclidean-distance) from a set of colors with known names to find the closest matching colour and it's name.
8
+
9
+ Mike Bostock of [D3](http://d3js.org/) fame [explains it well](https://gist.github.com/mbostock/3014589):
10
+
11
+ > Lab and HCL color spaces are special in that the perceived difference between two colors is proportional to their Euclidean distance in color space. This special property, called perceptual uniformity, makes them ideal for accurate visual encoding of data. In contrast, the more familiar RGB and HSL color spaces distort data when used for visualization.
12
+
13
+ ## Lists
14
+
15
+ The color names are derived from several lists:
16
+
17
+ - [roygbiv](lib/color_namer_rails/roygbiv.rb)
18
+ - [basic](lib/color_namer_rails/basic.rb)
19
+ - [html](lib/color_namer_rails/html.rb) - the HTML color names.
20
+ - [x11](lib/color_namer_rails/x11.rb) - The list that preceded the HTML color names
21
+ - [pantone](lib/color_namer_rails/pantone.rb)
22
+ - [ntc](lib/color_namer_rails/ntc.rb), an [astounding collection](http://chir.ag/projects/ntc/) of over 1500 named colors.
23
+
24
+ ## Installation
25
+
26
+ Install the gem and add to the application's Gemfile by executing:
27
+
28
+ ```bash
29
+ bundle add color_name_ruby
30
+ ```
31
+
32
+ If bundler is not being used to manage dependencies, install the gem by executing:
33
+
34
+ ```bash
35
+ gem install color_name_ruby
36
+ ```
37
+
38
+ ## Usage
39
+
40
+ Get a single name for a colour using `.get_name` by passing a colour in a way that [ColorConversion]((https://github.com/devrieda/color_conversion)) accepts.
41
+ When passing colours with their properties assigned to keys, you need to pass nil or an empty string as the first parameter.
42
+
43
+ ```ruby
44
+ ColorNamerRuby::Namer.get_name('#3672b4')
45
+ => 'Azure'
46
+
47
+ ColorNamerRuby::Namer.get_name('', r: 70, g: 130, b: 180, a: 0.5)
48
+ => 'steelblue'
49
+
50
+ ColorNamerRuby:Namer.get_name('', r: 130, g: 180, b: 70)
51
+ => 'Sushi'
52
+
53
+ ColorNamerRuby:Namer.get_name('', h: 20, s: 73, l: 20)
54
+ => 'Cioccolato'
55
+
56
+ ColorNamerRuby:Namer.get_name(nil, h: 107, s: 61, v: 71)
57
+ => 'Apple'
58
+
59
+ ColorNamerRuby::Namer.get_name(nil, h: 61, s: 71, b: 32)
60
+ => 'Camouflage'
61
+
62
+ ColorNamerRuby::Namer.get_name(nil, c: 71, m: 15, y: 5, k: 54)
63
+ => 'Blue Dianne'
64
+
65
+ ColorNamerRuby::Namer.get_name('rgb(51, 102, 204)')
66
+ => 'Denim'
67
+
68
+ ColorNamerRuby::Namer.get_name('hsl(225, 73%, 57%)')
69
+ => 'royalblue'
70
+ ```
71
+
72
+ Get a list of colour names sorted by their perceptual similarity to the given color by using `.get_names`.
73
+ Again, when passing colours with their properties assigned to keys, you need to pass nil or an empty string as the first parameter.
74
+
75
+ ```ruby
76
+ ColorNamerRuby::Namer.get_names('#3672b4')
77
+ => [
78
+ => { name: 'Azure', hex: '#315BA1', distance: 8.660254037844387 },
79
+ => { name: 'St Tropaz', hex: '#2D569B', distance: 9.9498743710662 },
80
+ => { name: 'Denim', hex: '#2B6CC4', distance: 10.816653826391969 },
81
+ => { name: 'steelblue', hex: '#4682B4', distance: 11.180339887498949 },
82
+ => { name: 'Steel Blue', hex: '#4682B4', distance: 11.180339887498949 },
83
+ => .
84
+ => .
85
+ => .
86
+ => ]
87
+ ```
88
+
89
+ Get a list of the colour lists that can be checked against.
90
+
91
+ ```ruby
92
+ ColorNamerRuby::Namer.list_names
93
+ => ['basic', 'html', 'ntc', 'pantone', 'roygbiv', 'x11']
94
+ ```
95
+
96
+ ## Options
97
+
98
+ ### pick
99
+
100
+ This parameter allows you to filter names from the dedicated lists for faster computation.
101
+ It can be used for both `get_name` and `get_names`.
102
+
103
+ ```ruby
104
+ ColorNamerRuby::Namer.get_names('#3672b4', pick: ['basic', 'x11'])
105
+ ```
106
+
107
+ ### omit
108
+
109
+ The opposite of `options.pick`.
110
+ It can be used for both `get_name` and `get_names`.
111
+
112
+ ```ruby
113
+ ColorNamerRuby::Namer.get_names('#3672b4', omit: ['pantone', 'roygbiv'])
114
+ ```
115
+
116
+ ### limit
117
+
118
+ This option allows us to limit the number of names that are returned to keep the returned output manageable.
119
+ It can be used for `get_names` (since `get_name` already has a limit of 1).
120
+
121
+ ```ruby
122
+ ColorNamerRuby::Namer.get_names('#3672b4', limit: 5)
123
+ ```
124
+
125
+ ###
126
+
127
+ ## Development
128
+
129
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
130
+
131
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
132
+
133
+ ## Contributing
134
+
135
+ Bug reports and pull requests are welcome on GitHub at <https://github.com/[USERNAME]/color_namer_ruby>. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/color_namer_ruby/blob/master/CODE_OF_CONDUCT.md).
136
+
137
+ ## License
138
+
139
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
140
+
141
+ ## Code of Conduct
142
+
143
+ Everyone interacting in the ColorNamerRuby project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/color_namer_ruby/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,36 @@
1
+ module ColorNamerRuby
2
+ class Basic
3
+ def self.get_name_from_hex(hex)
4
+ self.colours.select { |swatch| swatch[:hex] == hex.upcase }.first&.dig(:name)
5
+ end
6
+
7
+ private
8
+
9
+ def self.colours
10
+ [
11
+ { name: 'black', hex: '#000000' },
12
+ { name: 'blue', hex: '#0000FF' },
13
+ { name: 'cyan', hex: '#00FFFF' },
14
+ { name: 'green', hex: '#008000' },
15
+ { name: 'teal', hex: '#008080' },
16
+ { name: 'turquoise', hex: '#40E0D0' },
17
+ { name: 'indigo', hex: '#4B0082' },
18
+ { name: 'gray', hex: '#808080' },
19
+ { name: 'purple', hex: '#800080' },
20
+ { name: 'brown', hex: '#A52A2A' },
21
+ { name: 'tan', hex: '#D2B48C' },
22
+ { name: 'violet', hex: '#EE82EE' },
23
+ { name: 'beige', hex: '#F5F5DC' },
24
+ { name: 'fuchsia', hex: '#FF00FF' },
25
+ { name: 'gold', hex: '#FFD700' },
26
+ { name: 'magenta', hex: '#FF00FF' },
27
+ { name: 'orange', hex: '#FFA500' },
28
+ { name: 'pink', hex: '#FFC0CB' },
29
+ { name: 'red', hex: '#FF0000' },
30
+ { name: 'white', hex: '#FFFFFF' },
31
+ { name: 'yellow', hex: '#FFFF00' },
32
+ ]
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,44 @@
1
+ require 'color_conversion'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ module ColorNamerRuby
5
+ class Distance
6
+ def self.get_names_from_hex(hex, pick, omit, limit)
7
+ @colour = ColorConversion::Color.new(hex)
8
+
9
+ colour_lists = []
10
+
11
+ ColorNamerRuby::Namer.list_names.each do |list_name|
12
+ if (pick.empty? || pick.include?(list_name)) && !omit.include?(list_name)
13
+ colour_lists += self.get_colour_distances_in_list(Object.const_get("ColorNamerRuby::#{list_name.capitalize}").colours)
14
+ end
15
+ end
16
+
17
+ colour_lists = colour_lists.flatten.compact.reject(&:empty?)
18
+
19
+ limit = colour_lists.length if limit < 0
20
+
21
+ colour_lists.sort_by { |swatch| swatch[:distance] }.take(limit)
22
+ end
23
+
24
+ private
25
+
26
+ def self.get_colour_distances_in_list(colour_list)
27
+ colour_list.map do |swatch|
28
+ swatch[:distance] = self.distance_between_colours(ColorConversion::Color.new(swatch.dig(:hex)))
29
+ end
30
+
31
+ colour_list
32
+ end
33
+
34
+ def self.distance_between_colours(comparison_colour)
35
+ # https://en.wikipedia.org/wiki/Euclidean_distance#Higher_dimensions
36
+ # closest colours across the different arrays
37
+ # TODO use LAB or HCL instead of HSL
38
+ hsl_1 = @colour.hsl
39
+ hsl_2 = comparison_colour.hsl
40
+
41
+ Math.sqrt((hsl_1[:h] - hsl_2[:h])**2 + (hsl_1[:s] - hsl_2[:s])**2 + (hsl_1[:l] - hsl_2[:l])**2)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,163 @@
1
+ module ColorNamerRuby
2
+ class Html
3
+ def self.get_name_from_hex(hex)
4
+ self.colours.select { |swatch| swatch[:hex] == hex.upcase }.first&.dig(:name)
5
+ end
6
+
7
+ private
8
+
9
+ def self.colours
10
+ [
11
+ { name: 'aqua', hex: '#00FFFF' },
12
+ { name: 'aliceblue', hex: '#F0F8FF' },
13
+ { name: 'antiquewhite', hex: '#FAEBD7' },
14
+ { name: 'black', hex: '#000000' },
15
+ { name: 'blue', hex: '#0000FF' },
16
+ { name: 'cyan', hex: '#00FFFF' },
17
+ { name: 'darkblue', hex: '#00008B' },
18
+ { name: 'darkcyan', hex: '#008B8B' },
19
+ { name: 'darkgreen', hex: '#006400' },
20
+ { name: 'darkturquoise', hex: '#00CED1' },
21
+ { name: 'deepskyblue', hex: '#00BFFF' },
22
+ { name: 'green', hex: '#008000' },
23
+ { name: 'lime', hex: '#00FF00' },
24
+ { name: 'mediumblue', hex: '#0000CD' },
25
+ { name: 'mediumspringgreen', hex: '#00FA9A' },
26
+ { name: 'navy', hex: '#000080' },
27
+ { name: 'springgreen', hex: '#00FF7F' },
28
+ { name: 'teal', hex: '#008080' },
29
+ { name: 'midnightblue', hex: '#191970' },
30
+ { name: 'dodgerblue', hex: '#1E90FF' },
31
+ { name: 'lightseagreen', hex: '#20B2AA' },
32
+ { name: 'forestgreen', hex: '#228B22' },
33
+ { name: 'seagreen', hex: '#2E8B57' },
34
+ { name: 'darkslategray', hex: '#2F4F4F' },
35
+ { name: 'darkslategrey', hex: '#2F4F4F' },
36
+ { name: 'limegreen', hex: '#32CD32' },
37
+ { name: 'mediumseagreen', hex: '#3CB371' },
38
+ { name: 'turquoise', hex: '#40E0D0' },
39
+ { name: 'royalblue', hex: '#4169E1' },
40
+ { name: 'steelblue', hex: '#4682B4' },
41
+ { name: 'darkslateblue', hex: '#483D8B' },
42
+ { name: 'mediumturquoise', hex: '#48D1CC' },
43
+ { name: 'indigo', hex: '#4B0082' },
44
+ { name: 'darkolivegreen', hex: '#556B2F' },
45
+ { name: 'cadetblue', hex: '#5F9EA0' },
46
+ { name: 'cornflowerblue', hex: '#6495ED' },
47
+ { name: 'mediumaquamarine', hex: '#66CDAA' },
48
+ { name: 'dimgray', hex: '#696969' },
49
+ { name: 'dimgrey', hex: '#696969' },
50
+ { name: 'slateblue', hex: '#6A5ACD' },
51
+ { name: 'olivedrab', hex: '#6B8E23' },
52
+ { name: 'slategray', hex: '#708090' },
53
+ { name: 'slategrey', hex: '#708090' },
54
+ { name: 'lightslategray', hex: '#778899' },
55
+ { name: 'lightslategrey', hex: '#778899' },
56
+ { name: 'mediumslateblue', hex: '#7B68EE' },
57
+ { name: 'lawngreen', hex: '#7CFC00' },
58
+ { name: 'aquamarine', hex: '#7FFFD4' },
59
+ { name: 'chartreuse', hex: '#7FFF00' },
60
+ { name: 'gray', hex: '#808080' },
61
+ { name: 'grey', hex: '#808080' },
62
+ { name: 'maroon', hex: '#800000' },
63
+ { name: 'olive', hex: '#808000' },
64
+ { name: 'purple', hex: '#800080' },
65
+ { name: 'lightskyblue', hex: '#87CEFA' },
66
+ { name: 'skyblue', hex: '#87CEEB' },
67
+ { name: 'blueviolet', hex: '#8A2BE2' },
68
+ { name: 'darkmagenta', hex: '#8B008B' },
69
+ { name: 'darkred', hex: '#8B0000' },
70
+ { name: 'saddlebrown', hex: '#8B4513' },
71
+ { name: 'darkseagreen', hex: '#8FBC8F' },
72
+ { name: 'lightgreen', hex: '#90EE90' },
73
+ { name: 'mediumpurple', hex: '#9370DB' },
74
+ { name: 'darkviolet', hex: '#9400D3' },
75
+ { name: 'palegreen', hex: '#98FB98' },
76
+ { name: 'darkorchid', hex: '#9932CC' },
77
+ { name: 'yellowgreen', hex: '#9ACD32' },
78
+ { name: 'sienna', hex: '#A0522D' },
79
+ { name: 'brown', hex: '#A52A2A' },
80
+ { name: 'darkgray', hex: '#A9A9A9' },
81
+ { name: 'darkgrey', hex: '#A9A9A9' },
82
+ { name: 'greenyellow', hex: '#ADFF2F' },
83
+ { name: 'lightblue', hex: '#ADD8E6' },
84
+ { name: 'paleturquoise', hex: '#AFEEEE' },
85
+ { name: 'lightsteelblue', hex: '#B0C4DE' },
86
+ { name: 'powderblue', hex: '#B0E0E6' },
87
+ { name: 'firebrick', hex: '#B22222' },
88
+ { name: 'darkgoldenrod', hex: '#B8860B' },
89
+ { name: 'mediumorchid', hex: '#BA55D3' },
90
+ { name: 'rosybrown', hex: '#BC8F8F' },
91
+ { name: 'darkkhaki', hex: '#BDB76B' },
92
+ { name: 'silver', hex: '#C0C0C0' },
93
+ { name: 'mediumvioletred', hex: '#C71585' },
94
+ { name: 'indianred', hex: '#CD5C5C' },
95
+ { name: 'peru', hex: '#CD853F' },
96
+ { name: 'chocolate', hex: '#D2691E' },
97
+ { name: 'tan', hex: '#D2B48C' },
98
+ { name: 'lightgray', hex: '#D3D3D3' },
99
+ { name: 'lightgrey', hex: '#D3D3D3' },
100
+ { name: 'thistle', hex: '#D8BFD8' },
101
+ { name: 'goldenrod', hex: '#DAA520' },
102
+ { name: 'orchid', hex: '#DA70D6' },
103
+ { name: 'palevioletred', hex: '#DB7093' },
104
+ { name: 'crimson', hex: '#DC143C' },
105
+ { name: 'gainsboro', hex: '#DCDCDC' },
106
+ { name: 'plum', hex: '#DDA0DD' },
107
+ { name: 'burlywood', hex: '#DEB887' },
108
+ { name: 'lightcyan', hex: '#E0FFFF' },
109
+ { name: 'lavender', hex: '#E6E6FA' },
110
+ { name: 'darksalmon', hex: '#E9967A' },
111
+ { name: 'palegoldenrod', hex: '#EEE8AA' },
112
+ { name: 'violet', hex: '#EE82EE' },
113
+ { name: 'azure', hex: '#F0FFFF' },
114
+ { name: 'honeydew', hex: '#F0FFF0' },
115
+ { name: 'khaki', hex: '#F0E68C' },
116
+ { name: 'lightcoral', hex: '#F08080' },
117
+ { name: 'sandybrown', hex: '#F4A460' },
118
+ { name: 'beige', hex: '#F5F5DC' },
119
+ { name: 'mintcream', hex: '#F5FFFA' },
120
+ { name: 'wheat', hex: '#F5DEB3' },
121
+ { name: 'whitesmoke', hex: '#F5F5F5' },
122
+ { name: 'ghostwhite', hex: '#F8F8FF' },
123
+ { name: 'lightgoldenrodyellow', hex: '#FAFAD2' },
124
+ { name: 'linen', hex: '#FAF0E6' },
125
+ { name: 'salmon', hex: '#FA8072' },
126
+ { name: 'oldlace', hex: '#FDF5E6' },
127
+ { name: 'bisque', hex: '#FFE4C4' },
128
+ { name: 'blanchedalmond', hex: '#FFEBCD' },
129
+ { name: 'coral', hex: '#FF7F50' },
130
+ { name: 'cornsilk', hex: '#FFF8DC' },
131
+ { name: 'darkorange', hex: '#FF8C00' },
132
+ { name: 'deeppink', hex: '#FF1493' },
133
+ { name: 'floralwhite', hex: '#FFFAF0' },
134
+ { name: 'fuchsia', hex: '#FF00FF' },
135
+ { name: 'gold', hex: '#FFD700' },
136
+ { name: 'hotpink', hex: '#FF69B4' },
137
+ { name: 'ivory', hex: '#FFFFF0' },
138
+ { name: 'lavenderblush', hex: '#FFF0F5' },
139
+ { name: 'lemonchiffon', hex: '#FFFACD' },
140
+ { name: 'lightpink', hex: '#FFB6C1' },
141
+ { name: 'lightsalmon', hex: '#FFA07A' },
142
+ { name: 'lightyellow', hex: '#FFFFE0' },
143
+ { name: 'magenta', hex: '#FF00FF' },
144
+ { name: 'mistyrose', hex: '#FFE4E1' },
145
+ { name: 'moccasin', hex: '#FFE4B5' },
146
+ { name: 'navajowhite', hex: '#FFDEAD' },
147
+ { name: 'orange', hex: '#FFA500' },
148
+ { name: 'orangered', hex: '#FF4500' },
149
+ { name: 'papayawhip', hex: '#FFEFD5' },
150
+ { name: 'peachpuff', hex: '#FFDAB9' },
151
+ { name: 'pink', hex: '#FFC0CB' },
152
+ { name: 'red', hex: '#FF0000' },
153
+ { name: 'seashell', hex: '#FFF5EE' },
154
+ { name: 'snow', hex: '#FFFAFA' },
155
+ { name: 'tomato', hex: '#FF6347' },
156
+ { name: 'white', hex: '#FFFFFF' },
157
+ { name: 'yellow', hex: '#FFFF00' },
158
+ ]
159
+ end
160
+ end
161
+ end
162
+
163
+
@@ -0,0 +1,44 @@
1
+ require 'color_conversion'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ module ColorNamerRuby
5
+ class Namer
6
+ def self.get_name(colour_value, pick: [], omit: [], **alt_colour_value)
7
+ # alt_colour_value are used to collect colour paramaters when they are passed in the key format
8
+ @hex = ColorConversion::Color.new(colour_value.presence || alt_colour_value).hex
9
+
10
+ name = self.check_lists(pick, omit)
11
+ return name if name.present?
12
+
13
+ name_object = ColorNamerRuby::Distance.get_names_from_hex(@hex, pick, omit, 1).first
14
+ return name_object.dig(:name)
15
+ end
16
+
17
+ def self.get_names(colour_value, pick: [], omit: [], limit: -1, **alt_colour_value)
18
+ @hex = ColorConversion::Color.new(colour_value.presence || alt_colour_value).hex
19
+
20
+ name_objects = ColorNamerRuby::Distance.get_names_from_hex(@hex, pick, omit, limit)
21
+ return name_objects
22
+ end
23
+
24
+ def self.list_names
25
+ ['basic', 'html', 'ntc', 'pantone', 'roygbiv', 'x11']
26
+ end
27
+
28
+ private
29
+
30
+ def self.check_lists(pick, omit)
31
+ name = nil
32
+
33
+ self.list_names.each do |list_name|
34
+ if (pick.empty? || pick.include?(list_name)) && !omit.include?(list_name)
35
+ name = Object.const_get("ColorNamerRuby::#{list_name.capitalize}").get_name_from_hex(@hex)
36
+ end
37
+
38
+ break if name.present?
39
+ end
40
+
41
+ name || ''
42
+ end
43
+ end
44
+ end