color-tools 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/Changelog CHANGED
@@ -1,6 +1,16 @@
1
+ == color-utils 1.2.0
2
+ * Changed installer from a custom-written install.rb to setup.rb
3
+ 3.3.1-modified.
4
+ * Added Color::GreyScale (or Color::GrayScale).
5
+ * Added Color::YIQ. This colour definition is incomplete; it does not have
6
+ conversions from YIQ to other colour spaces.
7
+
1
8
  == color-utils 1.1.0
2
9
  * Added color/palette/gimp to support the reading and use of GIMP color
3
10
  palettes.
4
11
 
5
12
  == color-utils 1.0.0
6
13
  * Initial release.
14
+
15
+ $Id: Changelog,v 1.4 2005/07/01 15:54:18 austin Exp $
16
+ # vim: sts=2 sw=2 ts=4 et ai tw=77
data/Install CHANGED
@@ -1,6 +1,9 @@
1
1
  Installing this package is as simple as:
2
2
 
3
- % ruby install.rb
3
+ % ruby setup.rb
4
4
 
5
5
  Alternatively, you can use the RubyGem version of color-tools available as
6
- color-tools-1.1.0.gem from the usual sources.
6
+ color-tools-1.2.0.gem from the usual sources.
7
+
8
+ $Id: Install,v 1.4 2005/07/01 15:54:18 austin Exp $
9
+ # vim: sts=2 sw=2 ts=4 et ai tw=77
data/README CHANGED
@@ -1,17 +1,19 @@
1
1
  = color-tools README
2
- color-tools is a Ruby library to provide RGB and CMYK colour support to
3
- applications that require it. It provides 148 named RGB colours that are
4
- commonly supported and used in HTML, colour manipulation operations, and
5
- a monochromatic contrasting palette generator. With version 1.1, the
6
- ability to read and use GIMP colour palette definition files has been
7
- added.
2
+ color-tools is a Ruby library to provide RGB, CMYK, and other colour
3
+ support to applications that require it. It provides 148 named RGB colours
4
+ that are commonly supported and used in HTML, colour manipulation
5
+ operations, and a monochromatic contrasting palette generator. Version 1.2
6
+ introduces two new colour spaces: GrayScale (also known as GreyScale) and
7
+ YIQ (NTSC).
8
+
9
+ The GreyScale colour space has been added primarily to add new colour
10
+ space support for PDF::Writer (PDF documents support CMYK, RGB, and Grey
11
+ device colour spaces). The YIQ colour space has been promoted to a full
12
+ colour class to make future colour management of this class easier.
8
13
 
9
14
  == Copyright
10
15
  Copyright 2005 by Austin Ziegler
11
16
 
12
- Color::RGB and Color::CMYK were originally developed for the Ruby PDF
13
- project and PDF::Writer and represent wholly unique code.
14
-
15
17
  Color::Palette was developed based on techniques described by Andy
16
18
  "Malarkey" Clarke[1], implemented in JavaScript by Steve G. Chipman at
17
19
  SlayerOffice[2] and by Patrick Fitzgerald of BarelyFitz[3] in PHP.
@@ -29,17 +31,20 @@ conditions:
29
31
  products derived from this software without specific prior written
30
32
  permission.
31
33
 
32
- The above copyright notice and this permission notice shall be included
33
- in all copies or substantial portions of the Software.
34
+ The above copyright notice and this permission notice shall be included in
35
+ all copies or substantial portions of the Software.
34
36
 
35
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
36
- OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
37
- ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
38
- SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
39
- OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
40
- ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
41
- OTHER DEALINGS IN THE SOFTWARE.
37
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
38
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
39
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
40
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
41
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
43
+ DEALINGS IN THE SOFTWARE.
42
44
 
43
45
  [1] http://www.stuffandnonsense.co.uk/archives/creating_colour_palettes.html
44
46
  [2] http://slayeroffice.com/tools/color_palette/
45
47
  [3] http://www.barelyfitz.com/projects/csscolor/
48
+
49
+ $Id: README,v 1.5 2005/07/01 15:54:18 austin Exp $
50
+ # vim: sts=2 sw=2 ts=4 et ai tw=74
data/Rakefile CHANGED
@@ -1,4 +1,7 @@
1
1
  #! /usr/bin/env rake
2
+ # $Id: Rakefile,v 1.5 2005/07/01 15:54:18 austin Exp $
3
+ # vim: sts=2 sw=2 ts=4 et ai tw=77
4
+
2
5
  $LOAD_PATH.unshift('lib')
3
6
 
4
7
  require 'rubygems'
@@ -75,7 +78,7 @@ file TARDIST => [ :test ] do |t|
75
78
  else
76
79
  mode = 0644
77
80
  end
78
- data = File.read(dd)
81
+ data = File.open(dd, "rb") { |ff| ff.read }
79
82
  { :name => ddnew, :mode => mode, :data => data, :size => data.size,
80
83
  :mtime => mtime }
81
84
  end
@@ -36,12 +36,21 @@
36
36
  # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
37
37
  # DEALINGS IN THE SOFTWARE.
38
38
 
39
+ module Color
40
+ COLOR_TOOLS_VERSION = '1.2.0'
41
+
42
+ class RGB; end
43
+ class CMYK; end
44
+ class GrayScale; end
45
+ class YIQ; end
46
+ end
47
+
39
48
  require 'color/rgb'
40
49
  require 'color/cmyk'
50
+ require 'color/grayscale'
51
+ require 'color/yiq'
41
52
 
42
53
  module Color
43
- COLOR_TOOLS_VERSION = '1.1.0'
44
-
45
54
  Black = Color::RGB.new
46
55
  Navy = Color::RGB.new(0x00, 0x00, 0x80)
47
56
  DarkBlue = Color::RGB.new(0x00, 0x00, 0x8b)
@@ -5,69 +5,134 @@
5
5
  # http://rubyforge.org/ruby-pdf/
6
6
  #++
7
7
 
8
- require 'color/rgb'
8
+ # An CMYK colour object.
9
+ class Color::CMYK
10
+ PDF_FORMAT_STR = "%.3f %.3f %.3f %.3f %s"
9
11
 
10
- module Color
11
- # An CMYK colour object.
12
- class CMYK
13
- PDF_FORMAT_STR = "%.3f %.3f %.3f %.3f %s"
14
-
15
- def ==(other)
16
- other = other.to_cmyk if other.kind_of?(Color::RGB)
17
- other.kind_of?(Color::CMYK) and
18
- (@c == other.c) and
19
- (@m == other.m) and
20
- (@y == other.y) and
21
- (@k == other.k)
22
- end
12
+ # Compares the other colour to this one. The other colour will be
13
+ # converted to CMYK before comparison, so the comparison between a CMYK
14
+ # colour and a non-CMYK colour will be approximate and based on the
15
+ # other colour's #to_cmyk conversion. If there is no #to_cmyk
16
+ # conversion, this will raise an exception.
17
+ def ==(other)
18
+ other = other.to_cmyk
19
+ other.kind_of?(Color::CMYK) and
20
+ (@c == other.c) and
21
+ (@m == other.m) and
22
+ (@y == other.y) and
23
+ (@k == other.k)
24
+ end
23
25
 
24
- # Creates a CMYK colour object from fractional values 0 .. 1.
25
- def self.from_fraction(c = 0, m = 0, y = 0, k = 0)
26
- colour = Color::CMYK.new
27
- colour.instance_variable_set(:@c, c)
28
- colour.instance_variable_set(:@m, m)
29
- colour.instance_variable_set(:@y, y)
30
- colour.instance_variable_set(:@k, k)
31
- colour
32
- end
26
+ # Creates a CMYK colour object from fractional values 0 .. 1.
27
+ def self.from_fraction(c = 0, m = 0, y = 0, k = 0)
28
+ colour = Color::CMYK.new
29
+ colour.c = c
30
+ colour.m = m
31
+ colour.y = y
32
+ colour.k = k
33
+ colour
34
+ end
33
35
 
34
- # Creates a CMYK colour object from percentages.
35
- def initialize(c = 0, m = 0, y = 0, k = 0)
36
- @c = c / 100.0
37
- @m = m / 100.0
38
- @y = y / 100.0
39
- @k = k / 100.0
40
- end
36
+ # Creates a CMYK colour object from percentages.
37
+ def initialize(c = 0, m = 0, y = 0, k = 0)
38
+ @c = c / 100.0
39
+ @m = m / 100.0
40
+ @y = y / 100.0
41
+ @k = k / 100.0
42
+ end
41
43
 
42
- # Present the colour as a fill colour string for PDF.
43
- def pdf_fill
44
- PDF_FORMAT_STR % [ @c, @m, @y, @k, "k" ]
45
- end
44
+ # Present the colour as a DeviceCMYK fill colour string for PDF.
45
+ def pdf_fill
46
+ PDF_FORMAT_STR % [ @c, @m, @y, @k, "k" ]
47
+ end
46
48
 
47
- # Present the colour as a stroke colour string for PDF.
48
- def pdf_stroke
49
- PDF_FORMAT_STR % [ @c, @m, @y, @k, "K" ]
50
- end
49
+ # Present the colour as a DeviceCMYK stroke colour string for PDF.
50
+ def pdf_stroke
51
+ PDF_FORMAT_STR % [ @c, @m, @y, @k, "K" ]
52
+ end
51
53
 
52
- # Present the colour as an HTML/CSS colour string.
53
- def html
54
- to_rgb.html
55
- end
54
+ # Present the colour as an RGB HTML/CSS colour string. Note that this
55
+ # will perform a #to_rgb
56
+ def html
57
+ to_rgb.html
58
+ end
56
59
 
57
- # Convert the CMYK colour to RGB. Note that colour experts strongly
58
- # suggest that this is a *bad* idea, as CMYK represents percentages of
59
- # inks, not mixed colour intensities like RGB.
60
- def to_rgb
60
+ # Converts the CMYK colour to RGB. Most colour experts strongly suggest
61
+ # that this is not a good idea (some even suggesting that it's a very
62
+ # bad idea). CMYK represents additive percentages of inks on white
63
+ # paper, whereas RGB represents mixed colour intensities on a black
64
+ # screen.
65
+ #
66
+ # However, the colour conversion can be done, and there are two
67
+ # different methods for the conversion that provide slightly different
68
+ # results. Adobe PDF conversions are done with the first form.
69
+ #
70
+ # # Adobe PDF Display Formula
71
+ # r = 1.0 - min(1.0, c + k)
72
+ # g = 1.0 - min(1.0, m + k)
73
+ # b = 1.0 - min(1.0, y + k)
74
+ #
75
+ # # Other
76
+ # r = 1.0 - (c * (1.0 - k) + k)
77
+ # g = 1.0 - (m * (1.0 - k) + k)
78
+ # b = 1.0 - (y * (1.0 - k) + k)
79
+ #
80
+ # If we have a CMYK colour of [33% 66% 83% 25%], the first method will
81
+ # give an approximate RGB colour of (107, 23, 0) or #6b1700. The second
82
+ # method will give an approximate RGB colour of (128, 65, 33) or
83
+ # #804121. Which is correct? Although the colours may seem to be
84
+ # drastically different in the RGB colour space, they are very similar
85
+ # colours, differing mostly in intensity. The first is a darker,
86
+ # slightly redder brown; the second is a lighter brown.
87
+ #
88
+ # Because of this subtlety, both methods are now offered for conversion
89
+ # in color-tools 1.2 or later. The Adobe method is not used by default;
90
+ # to enable it, pass +true+ to #to_rgb.
91
+ def to_rgb(use_adobe_method = false)
92
+ if use_adobe_method
93
+ r = 1.0 - [1.0, @c + @k].min
94
+ g = 1.0 - [1.0, @m + @k].min
95
+ b = 1.0 - [1.0, @y + @k].min
96
+ else
61
97
  r = 1.0 - (@c.to_f * (1.0 - @k.to_f) + @k.to_f)
62
98
  g = 1.0 - (@m.to_f * (1.0 - @k.to_f) + @k.to_f)
63
99
  b = 1.0 - (@y.to_f * (1.0 - @k.to_f) + @k.to_f)
64
- Color::RGB.from_fraction(r, g, b)
65
100
  end
101
+ Color::RGB.from_fraction(r, g, b)
102
+ end
66
103
 
67
- def to_cmyk
68
- self.dup
69
- end
104
+ # Converts the CMYK colour to a single greyscale value. There are
105
+ # undoubtedly multiple methods for this conversion, but only a minor
106
+ # variant of the Adobe conversion method will be used:
107
+ #
108
+ # g = 1.0 - min(1.0, 0.299 * c + 0.587 * m + 0.114 * y + k)
109
+ #
110
+ # This treats the CMY values similarly to YIQ (NTSC) values and then
111
+ # adds the level of black. This is a variant of the Adobe version
112
+ # because it uses the more precise YIQ (NTSC) conversion values for Y
113
+ # (intensity) rather than the approximates provided by Adobe (0.3, 0.59,
114
+ # and 0.11).
115
+ def to_grayscale
116
+ c = 0.299 * @c.to_f
117
+ m = 0.587 * @m.to_f
118
+ y = 0.114 * @y.to_f
119
+ g = 1.0 - [1.0, c + m + y + @k].min
120
+ Color::Grayscale.from_fraction(g)
121
+ end
122
+ alias to_greyscale to_grayscale
123
+
124
+ def to_cmyk
125
+ self
126
+ end
70
127
 
71
- attr_accessor :c, :m, :y, :k
128
+ # Returns the YIQ (NTSC) colour approximation of the CMYK value. This is
129
+ # done by first con
130
+ def to_yiq
131
+ y = (@r * 0.299) + (@g * 0.587) + (@b * 0.114)
132
+ i = (@r * 0.596) + (@g * -0.275) + (@b * -0.321)
133
+ q = (@r * 0.212) + (@g * -0.523) + (@b * 0.311)
134
+ Color::YIQ.from_fraction(y, i, q)
72
135
  end
136
+
137
+ attr_accessor :c, :m, :y, :k
73
138
  end
@@ -0,0 +1,105 @@
1
+ #--
2
+ # Colour management with Ruby.
3
+ #
4
+ # Copyright 2005 Austin Ziegler
5
+ # http://rubyforge.org/ruby-pdf/
6
+ #++
7
+
8
+ # A colour object representing shades of grey. Used primarily in PDF
9
+ # document creation.
10
+ class Color::GrayScale
11
+ # The format required to present the colour to a PDF document.
12
+ PDF_FORMAT_STR = "%.3f %s"
13
+
14
+ # Creates a greyscale colour object from fractional values 0 .. 1.
15
+ def self.from_fraction(g = 0)
16
+ color = Color::GrayScale.new
17
+ color.g = g
18
+ color
19
+ end
20
+
21
+ # Creates a greyscale colour object from percentages 0 .. 100.
22
+ def initialize(g = 0)
23
+ @g = g / 100.0
24
+ end
25
+
26
+ # Compares the other colour to this one. The other colour will be
27
+ # converted to GreyScale before comparison, so the comparison between a
28
+ # GreyScale colour and a non-GreyScale colour will be approximate and
29
+ # based on the other colour's #to_greyscale conversion. If there is no
30
+ # #to_greyscale conversion, this will raise an exception.
31
+ def ==(other)
32
+ other = other.to_grayscale
33
+ other.kind_of?(Color::GrayScale) and (@g == other.g)
34
+ end
35
+
36
+ # Present the colour as a fill colour string for PDF.
37
+ def pdf_fill
38
+ PDF_FORMAT_STR % [ @g, "g" ]
39
+ end
40
+
41
+ # Present the colour as a stroke colour string for PDF.
42
+ def pdf_stroke
43
+ PDF_FORMAT_STR % [ @g, "G" ]
44
+ end
45
+
46
+ def to_255
47
+ [(@g * 255).round, 255].min
48
+ end
49
+ private :to_255
50
+
51
+ # Present the colour as an HTML/CSS colour string.
52
+ def html
53
+ gs = "%02x" % @g.to_255
54
+ "##{gs * 3}"
55
+ end
56
+
57
+ # Convert the greyscale colour to CMYK.
58
+ def to_cmyk
59
+ k = 1.0 - @g.to_f
60
+ Color::CMYK.from_Fraction(0, 0, 0, k)
61
+ end
62
+
63
+ # Convert the greyscale colour to RGB.
64
+ def to_rgb(ignored = true)
65
+ g = @g.to_255
66
+ Color::RGB.new(g, g, g)
67
+ end
68
+
69
+ def to_grayscale
70
+ self
71
+ end
72
+ alias to_greyscale to_grayscale
73
+
74
+ # Lightens the greyscale colour by the stated percent.
75
+ def lighten_by(percent)
76
+ g = [@g + (@g * (percent / 100.0)), 1.0].min
77
+ Color::Grayscale.from_fraction(g)
78
+ end
79
+
80
+ # Darken the RGB hue by the stated percent.
81
+ def darken_by(percent)
82
+ g = [@g - (@g * (percent / 100.0)), 1.0].max
83
+ Color::GrayScale.from_fraction(g)
84
+ end
85
+
86
+ # Returns the YIQ (NTSC) colour encoding of the greyscale value. This
87
+ # is an approximation, as the values for I and Q are calculated by
88
+ # treating the greyscale value as an RGB value. The Y (intensity or
89
+ # brightness) value is the same as the greyscale value.
90
+ def to_yiq
91
+ y = @g
92
+ i = (@g * 0.596) + (@g * -0.275) + (@g * -0.321)
93
+ q = (@g * 0.212) + (@g * -0.523) + (@g * 0.311)
94
+ Color::YIQ.from_fraction(y, i, q)
95
+ end
96
+
97
+ # Returns the brightness value for this greyscale value; this is the
98
+ # greyscale value.
99
+ def brightness
100
+ @g
101
+ end
102
+
103
+ attr_accessor :g
104
+ end
105
+ Color::GreyScale = Color::GrayScale
@@ -5,151 +5,171 @@
5
5
  # http://rubyforge.org/ruby-pdf/
6
6
  #++
7
7
 
8
- require 'color/cmyk'
9
-
10
- module Color
11
- # An RGB colour object.
12
- class RGB
13
- # The format required to present the colour to a PDF document.
14
- PDF_FORMAT_STR = "%.3f %.3f %.3f %s"
15
-
16
- class << self
17
- # Creates an RGB colour object from percentages 0 .. 100.
18
- def from_percentage(r = 0, g = 0, b = 0)
19
- from_fraction(r / 100.0, g / 100.0, b / 100.0)
20
- end
21
-
22
- # Creates an RGB colour object from fractional values 0 .. 1.
23
- def from_fraction(r = 0.0, g = 0.0, b = 0.0)
24
- colour = Color::RGB.new
25
- colour.instance_variable_set(:@r, r)
26
- colour.instance_variable_set(:@g, g)
27
- colour.instance_variable_set(:@b, b)
28
- colour
29
- end
30
-
31
- # Creates an RGB colour object from an HTML colour descriptor (e.g.,
32
- # <tt>"fed"</tt> or <tt>"#cabbed;"</tt>.
33
- def from_html(html_colour)
34
- html_colour = html_colour.gsub(%r{[#;]}, '')
35
- case html_colour.size
36
- when 3
37
- colours = html_colour.scan(%r{[0-9A-Fa-f]}).map { |el| (el * 2).to_i(16) }
38
- when 6
39
- colours = html_colour.scan(%r<[0-9A-Fa-f]{2}>).map { |el| el.to_i(16) }
40
- else
41
- raise ArgumentError
42
- end
43
-
44
- Color::RGB.new(*colours)
45
- end
8
+ # An RGB colour object.
9
+ class Color::RGB
10
+ # The format required to present the colour to a PDF document.
11
+ PDF_FORMAT_STR = "%.3f %.3f %.3f %s"
12
+
13
+ class << self
14
+ # Creates an RGB colour object from percentages 0 .. 100.
15
+ def from_percentage(r = 0, g = 0, b = 0)
16
+ from_fraction(r / 100.0, g / 100.0, b / 100.0)
46
17
  end
47
18
 
48
- def ==(other)
49
- other = other.to_rgb
50
- other.kind_of?(Color::RGB) and
51
- (@r == other.r) and
52
- (@g == other.g) and
53
- (@b == other.b)
19
+ # Creates an RGB colour object from fractional values 0 .. 1.
20
+ def from_fraction(r = 0.0, g = 0.0, b = 0.0)
21
+ colour = Color::RGB.new
22
+ colour.r = r
23
+ colour.g = g
24
+ colour.b = b
25
+ colour
54
26
  end
55
27
 
56
- # Creates an RGB colour object from the standard range 0 .. 255.
57
- def initialize(r = 0, g = 0, b = 0)
58
- @r = r / 255.0
59
- @g = g / 255.0
60
- @b = b / 255.0
61
- end
28
+ # Creates an RGB colour object from an HTML colour descriptor (e.g.,
29
+ # <tt>"fed"</tt> or <tt>"#cabbed;"</tt>.
30
+ def from_html(html_colour)
31
+ html_colour = html_colour.gsub(%r{[#;]}, '')
32
+ case html_colour.size
33
+ when 3
34
+ colours = html_colour.scan(%r{[0-9A-Fa-f]}).map { |el| (el * 2).to_i(16) }
35
+ when 6
36
+ colours = html_colour.scan(%r<[0-9A-Fa-f]{2}>).map { |el| el.to_i(16) }
37
+ else
38
+ raise ArgumentError
39
+ end
62
40
 
63
- # Present the colour as a fill colour string for PDF.
64
- def pdf_fill
65
- PDF_FORMAT_STR % [ @r, @g, @b, "rg" ]
41
+ Color::RGB.new(*colours)
66
42
  end
43
+ end
67
44
 
68
- # Present the colour as a stroke colour string for PDF.
69
- def pdf_stroke
70
- PDF_FORMAT_STR % [ @r, @g, @b, "RG" ]
71
- end
45
+ def ==(other)
46
+ other = other.to_rgb
47
+ other.kind_of?(Color::RGB) and
48
+ (@r == other.r) and
49
+ (@g == other.g) and
50
+ (@b == other.b)
51
+ end
72
52
 
73
- # Present the colour as an HTML/CSS colour string.
74
- def html
75
- r = (@r * 255).round
76
- r = 255 if r > 255
53
+ # Creates an RGB colour object from the standard range 0 .. 255.
54
+ def initialize(r = 0, g = 0, b = 0)
55
+ @r = r / 255.0
56
+ @g = g / 255.0
57
+ @b = b / 255.0
58
+ end
77
59
 
78
- g = (@g * 255).round
79
- g = 255 if g > 255
60
+ # Present the colour as a fill colour string for PDF.
61
+ def pdf_fill
62
+ PDF_FORMAT_STR % [ @r, @g, @b, "rg" ]
63
+ end
80
64
 
81
- b = (@b * 255).round
82
- b = 255 if b > 255
65
+ # Present the colour as a stroke colour string for PDF.
66
+ def pdf_stroke
67
+ PDF_FORMAT_STR % [ @r, @g, @b, "RG" ]
68
+ end
83
69
 
84
- "#%02x%02x%02x" % [ r, g, b ]
85
- end
70
+ # Present the colour as an HTML/CSS colour string.
71
+ def html
72
+ r = (@r * 255).round
73
+ r = 255 if r > 255
86
74
 
87
- # Convert the RGB colour to CMYK. Note that colour experts strongly
88
- # suggest that this is a *bad* idea, as CMYK represents percentages of
89
- # inks, not mixed colour intensities like RGB.
90
- def to_cmyk
91
- c = 1.0 - @r.to_f
92
- m = 1.0 - @g.to_f
93
- y = 1.0 - @b.to_f
75
+ g = (@g * 255).round
76
+ g = 255 if g > 255
94
77
 
95
- k = 1.0
96
- k = c if c < k
97
- k = m if m < k
98
- k = y if y < k
78
+ b = (@b * 255).round
79
+ b = 255 if b > 255
99
80
 
100
- c = (c.to_f - k.to_f) / (1.0 - k.to_f)
101
- m = (m.to_f - k.to_f) / (1.0 - k.to_f)
102
- y = (y.to_f - k.to_f) / (1.0 - k.to_f)
81
+ "#%02x%02x%02x" % [ r, g, b ]
82
+ end
103
83
 
104
- Color::CMYK.new(c, m, y, k)
105
- end
84
+ # Converts the RGB colour to CMYK. Most colour experts strongly suggest
85
+ # that this is not a good idea (some even suggesting that it's a very
86
+ # bad idea). CMYK represents additive percentages of inks on white
87
+ # paper, whereas RGB represents mixed colour intensities on a black
88
+ # screen.
89
+ #
90
+ # However, the colour conversion can be done. The basic method is
91
+ # multi-step:
92
+ #
93
+ # 1. Convert the R, G, and B components to C, M, and Y components.
94
+ # c = 1.0 � r
95
+ # m = 1.0 � g
96
+ # y = 1.0 � b
97
+ # 2. Compute the minimum amount of black (K) required to smooth the
98
+ # colour in inks.
99
+ # k = min(c, m, y)
100
+ # 3. Perform undercolour removal on the C, M, and Y components of the
101
+ # colours because less of each colour is needed for each bit of
102
+ # black. Also, regenerate the black (K) based on the undercolour
103
+ # removal so that the colour is more accurately represented in ink.
104
+ # c = min(1.0, max(0.0, c � UCR(k)))
105
+ # m = min(1.0, max(0.0, m � UCR(k)))
106
+ # y = min(1.0, max(0.0, y � UCR(k)))
107
+ # k = min(1.0, max(0.0, BG(k)))
108
+ #
109
+ # The undercolour removal function and the black generation functions
110
+ # return a value based on the brightness of the RGB colour.
111
+ def to_cmyk
112
+ c = 1.0 - @r.to_f
113
+ m = 1.0 - @g.to_f
114
+ y = 1.0 - @b.to_f
115
+
116
+ k = [c, m, y].min
117
+ k = k - (k * brightness)
118
+
119
+ c = [1.0, [0.0, c - k].max].min
120
+ m = [1.0, [0.0, m - k].max].min
121
+ y = [1.0, [0.0, y - k].max].min
122
+ k = [1.0, [0.0, k].max].min
123
+
124
+ Color::CMYK.from_fraction(c, m, y, k)
125
+ end
106
126
 
107
- def to_rgb
108
- self.dup
109
- end
127
+ def to_rgb(ignored = nil)
128
+ self
129
+ end
110
130
 
111
- # Lighten the RGB hue by the stated percent.
112
- def lighten_by(percent)
113
- mix_with(White, percent)
114
- end
131
+ # Lighten the RGB hue by the stated percent.
132
+ def lighten_by(percent)
133
+ mix_with(White, percent)
134
+ end
115
135
 
116
- # Darken the RGB hue by the stated percent.
117
- def darken_by(percent)
118
- mix_with(Black, percent)
119
- end
136
+ # Darken the RGB hue by the stated percent.
137
+ def darken_by(percent)
138
+ mix_with(Black, percent)
139
+ end
120
140
 
121
- # Mix the mask colour (which must be an RGB object) with the current
122
- # colour at the stated opacity percentage (0 .. 100).
123
- def mix_with(mask, opacity)
124
- opacity /= 100.0
125
- rgb = self.dup
141
+ # Mix the mask colour (which must be an RGB object) with the current
142
+ # colour at the stated opacity percentage (0 .. 100).
143
+ def mix_with(mask, opacity)
144
+ opacity /= 100.0
145
+ rgb = self.dup
126
146
 
127
- rgb.r = (@r * opacity) + (mask.r * (1 - opacity))
128
- rgb.g = (@g * opacity) + (mask.g * (1 - opacity))
129
- rgb.b = (@b * opacity) + (mask.b * (1 - opacity))
147
+ rgb.r = (@r * opacity) + (mask.r * (1 - opacity))
148
+ rgb.g = (@g * opacity) + (mask.g * (1 - opacity))
149
+ rgb.b = (@b * opacity) + (mask.b * (1 - opacity))
130
150
 
131
- rgb
132
- end
151
+ rgb
152
+ end
133
153
 
134
- # Returns the YIQ (NTSC) colour encoding of the RGB value.
135
- def to_yiq
136
- {
137
- :y => (@r * 0.299) + (@g * 0.587) + (@b * 0.114),
138
- :i => (@r * 0.596) + (@g * -0.275) + (@b * -0.321),
139
- :q => (@r * 0.212) + (@g * -0.523) + (@b * 0.311),
140
- }
141
- end
154
+ # Returns the YIQ (NTSC) colour encoding of the RGB value.
155
+ def to_yiq
156
+ y = (@r * 0.299) + (@g * 0.587) + (@b * 0.114)
157
+ i = (@r * 0.596) + (@g * -0.275) + (@b * -0.321)
158
+ q = (@r * 0.212) + (@g * -0.523) + (@b * 0.311)
159
+ Color::YIQ.from_fraction(y, i, q)
160
+ end
142
161
 
143
- # Returns the brightness value for a colour, a number between 0 and
144
- # 1. Based on the Y value of YIQ encoding, representing luminosity, or
145
- # perceived brightness.
146
- def brightness
147
- to_yiq[:y]
148
- end
162
+ # Returns the brightness value for a colour, a number between 0 and
163
+ # 1. Based on the Y value of YIQ encoding, representing luminosity, or
164
+ # perceived brightness.
165
+ def brightness
166
+ to_yiq.y
167
+ end
168
+ alias to_grayscale brightness
169
+ alias to_greyscale to_grayscale
149
170
 
150
- attr_accessor :r, :g, :b
171
+ attr_accessor :r, :g, :b
151
172
 
152
- White = RGB.new(255, 255, 255)
153
- Black = RGB.new(0, 0, 0)
154
- end
173
+ White = Color::RGB.new(255, 255, 255)
174
+ Black = Color::RGB.new(0, 0, 0)
155
175
  end