Class: Color::RGB
- Inherits:
-
Object
- Object
- Color::RGB
- Includes:
- Color
- Defined in:
- lib/color/rgb.rb,
lib/color.rb,
lib/color/rgb/colors.rb,
lib/color/rgb/contrast.rb,
lib/color/rgb/metallic.rb
Overview
An RGB colour object.
Defined Under Namespace
Modules: Metallic
Constant Summary collapse
- PDF_FORMAT_STR =
The format of a DeviceRGB colour for PDF. In color-tools 2.0 this will be removed from this package and added back as a modification by the PDF::Writer package.
"%.3f %.3f %.3f %s"
Constants included from Color
COLOR_EPSILON, COLOR_TOLERANCE, COLOR_VERSION, GreyScale
Class Method Summary collapse
-
.by_css(name_or_hex, &block) ⇒ Object
Return a colour as identified by the colour name, or by hex.
-
.by_hex(hex, &block) ⇒ Object
Find or create a colour by an HTML hex code.
-
.by_name(name, &block) ⇒ Object
Return a colour as identified by the colour name.
-
.extract_colors(text, mode = :both) ⇒ Object
Extract named or hex colours from the provided text.
-
.from_fraction(r = 0.0, g = 0.0, b = 0.0, &block) ⇒ Object
Creates an RGB colour object from fractional values 0..1.
-
.from_grayscale_fraction(l = 0.0, &block) ⇒ Object
(also: from_greyscale_fraction)
Creates an RGB colour object from a grayscale fractional value 0..1.
-
.from_html(html_colour, &block) ⇒ Object
Creates an RGB colour object from an HTML colour descriptor (e.g.,
"fed"
or"#cabbed;"
. -
.from_percentage(r = 0, g = 0, b = 0, &block) ⇒ Object
Creates an RGB colour object from percentages 0..100.
Instance Method Summary collapse
-
#+(other) ⇒ Object
Adds another colour to the current colour.
-
#-(other) ⇒ Object
Subtracts another colour to the current colour.
-
#-@ ⇒ Object
Numerically negate the color.
-
#adjust_brightness(percent) ⇒ Object
Returns a new colour with the brightness adjusted by the specified percentage.
-
#adjust_hue(percent) ⇒ Object
Returns a new colour with the hue adjusted by the specified percentage.
-
#adjust_saturation(percent) ⇒ Object
Returns a new colour with the saturation adjusted by the specified percentage.
-
#b ⇒ Object
Returns the blue component of the colour as a fraction in the range 0.0 ..
-
#b=(bb) ⇒ Object
Sets the blue component of the colour as a fraction in the range 0.0 ..
-
#blue ⇒ Object
Returns the blue component of the colour in the normal 0 ..
-
#blue=(bb) ⇒ Object
Sets the blue component of the colour in the normal 0 ..
-
#blue_p ⇒ Object
Returns the blue component of the colour as a percentage.
-
#blue_p=(bb) ⇒ Object
Sets the blue component of the colour as a percentage.
-
#brightness ⇒ Object
Returns the brightness value for a colour, a number between 0..1.
-
#closest_match(color_list, threshold_distance = 1000.0) ⇒ Object
Calculates and returns the closest match to this colour from a list of provided colours.
-
#coerce(other) ⇒ Object
Coerces the other Color object into RGB.
-
#contrast(other) ⇒ Object
Outputs how much contrast this color has with another RGB color.
-
#css_hsl ⇒ Object
Present the colour as an HSL HTML/CSS colour string (e.g., “hsl(180, 25%, 35%)”).
-
#css_hsla ⇒ Object
Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g., “hsla(180, 25%, 35%, 1)”).
-
#css_rgb ⇒ Object
Present the colour as an RGB HTML/CSS colour string (e.g., “rgb(0%, 50%, 100%)”).
-
#css_rgba(alpha = 1) ⇒ Object
Present the colour as an RGBA (with an optional alpha that defaults to 1) HTML/CSS colour string (e.g.,“rgb(0%, 50%, 100%, 1)”).
-
#darken_by(percent) ⇒ Object
Mix the RGB hue with Black so that the RGB hue is the specified percentage of the resulting colour.
-
#delta_e94(color_1, color_2, weighting_type = :graphic_arts) ⇒ Object
The Delta E (CIE94) algorithm en.wikipedia.org/wiki/Color_difference#CIE94.
-
#g ⇒ Object
Returns the green component of the colour as a fraction in the range 0.0 ..
-
#g=(gg) ⇒ Object
Sets the green component of the colour as a fraction in the range 0.0 ..
-
#green ⇒ Object
Returns the green component of the colour in the normal 0 ..
-
#green=(gg) ⇒ Object
Sets the green component of the colour in the normal 0 ..
-
#green_p ⇒ Object
Returns the green component of the colour as a percentage.
-
#green_p=(gg) ⇒ Object
Sets the green component of the colour as a percentage.
-
#hex ⇒ Object
Present the colour as an RGB hex triplet.
-
#html ⇒ Object
Present the colour as an HTML/CSS colour string.
-
#initialize(r = 0, g = 0, b = 0, radix = 255.0, &block) ⇒ RGB
constructor
Creates an RGB colour object from the standard range 0..255.
- #inspect ⇒ Object
-
#lighten_by(percent) ⇒ Object
Mix the RGB hue with White so that the RGB hue is the specified percentage of the resulting colour.
-
#max_rgb_as_grayscale ⇒ Object
(also: #max_rgb_as_greyscale)
Retrieve the maxmum RGB value from the current colour as a GrayScale colour.
-
#mix_with(mask, opacity) ⇒ Object
Mix the mask colour (which must be an RGB object) with the current colour at the stated opacity percentage (0..100).
-
#pdf_fill ⇒ Object
Present the colour as a DeviceRGB fill colour string for PDF.
-
#pdf_stroke ⇒ Object
Present the colour as a DeviceRGB stroke colour string for PDF.
-
#r ⇒ Object
Returns the red component of the colour as a fraction in the range 0.0 ..
-
#r=(rr) ⇒ Object
Sets the red component of the colour as a fraction in the range 0.0 ..
-
#red ⇒ Object
Returns the red component of the colour in the normal 0 ..
-
#red=(rr) ⇒ Object
Sets the red component of the colour in the normal 0 ..
-
#red_p ⇒ Object
Returns the red component of the colour as a percentage.
-
#red_p=(rr) ⇒ Object
Sets the red component of the colour as a percentage.
- #to_a ⇒ Object
-
#to_cmyk ⇒ Object
Converts the RGB colour to CMYK.
-
#to_grayscale ⇒ Object
(also: #to_greyscale)
Convert to grayscale.
-
#to_hsl ⇒ Object
Returns the HSL colour encoding of the RGB value.
-
#to_lab(color_space = :sRGB, reference_white = [ 95.047, 100.00, 108.883 ]) ⇒ Object
Returns the L*a*b* colour encoding of the value via the XYZ colour encoding.
- #to_rgb(ignored = nil) ⇒ Object
-
#to_xyz(color_space = :sRGB) ⇒ Object
Returns the XYZ colour encoding of the value.
-
#to_yiq ⇒ Object
Returns the YIQ (NTSC) colour encoding of the RGB value.
Methods included from Color
#==, coerce, const_missing, equivalent?, #name, #names, #names=, near?, near_one?, near_one_or_more?, near_zero?, near_zero_or_less?, new, normalize, normalize_byte, normalize_to_range, normalize_word
Constructor Details
Class Method Details
.by_css(name_or_hex, &block) ⇒ Object
Return a colour as identified by the colour name, or by hex.
648 649 650 |
# File 'lib/color/rgb.rb', line 648 def by_css(name_or_hex, &block) by_name(name_or_hex) { by_hex(name_or_hex, &block) } end |
.by_hex(hex, &block) ⇒ Object
Find or create a colour by an HTML hex code. This differs from the #from_html method in that if the colour code matches a named colour, the existing colour will be returned.
Color::RGB.by_hex('ff0000').name # => 'red'
Color::RGB.by_hex('ff0001').name # => nil
If a block is provided, the value that is returned by the block will be returned instead of the exception caused by an error in providing a correct hex format.
632 633 634 635 636 637 638 639 640 |
# File 'lib/color/rgb.rb', line 632 def by_hex(hex, &block) __by_hex.fetch(html_hexify(hex)) { from_html(hex) } rescue if block block.call else raise end end |
.by_name(name, &block) ⇒ Object
Return a colour as identified by the colour name.
643 644 645 |
# File 'lib/color/rgb.rb', line 643 def by_name(name, &block) __by_name.fetch(name.to_s.downcase, &block) end |
.extract_colors(text, mode = :both) ⇒ Object
Extract named or hex colours from the provided text.
653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 |
# File 'lib/color/rgb.rb', line 653 def extract_colors(text, mode = :both) text = text.downcase regex = case mode when :name Regexp.union(__by_name.keys) when :hex Regexp.union(__by_hex.keys) when :both Regexp.union(__by_hex.keys + __by_name.keys) end text.scan(regex).map { |match| case mode when :name by_name(match) when :hex by_hex(match) when :both by_css(match) end } end |
.from_fraction(r = 0.0, g = 0.0, b = 0.0, &block) ⇒ Object
Creates an RGB colour object from fractional values 0..1.
Color::RGB.from_fraction(.3, .2, .1)
592 593 594 |
# File 'lib/color/rgb.rb', line 592 def from_fraction(r = 0.0, g = 0.0, b = 0.0, &block) new(r, g, b, 1.0, &block) end |
.from_grayscale_fraction(l = 0.0, &block) ⇒ Object Also known as: from_greyscale_fraction
Creates an RGB colour object from a grayscale fractional value 0..1.
597 598 599 |
# File 'lib/color/rgb.rb', line 597 def from_grayscale_fraction(l = 0.0, &block) new(l, l, l, 1.0, &block) end |
.from_html(html_colour, &block) ⇒ Object
609 610 611 612 613 614 615 616 617 618 619 620 |
# File 'lib/color/rgb.rb', line 609 def from_html(html_colour, &block) # When we can move to 1.9+ only, this will be \h h = html_colour.scan(/[0-9a-f]/i) case h.size when 3 new(*h.map { |v| (v * 2).to_i(16) }, &block) when 6 new(*h.each_slice(2).map { |v| v.join.to_i(16) }, &block) else raise ArgumentError, "Not a supported HTML colour type." end end |
Instance Method Details
#+(other) ⇒ Object
Adds another colour to the current colour. The other colour will be converted to RGB before addition. This conversion depends upon a #to_rgb method on the other colour.
The addition is done using the RGB Accessor methods to ensure a valid colour in the result.
532 533 534 |
# File 'lib/color/rgb.rb', line 532 def +(other) self.class.from_fraction(r + other.r, g + other.g, b + other.b) end |
#-(other) ⇒ Object
Subtracts another colour to the current colour. The other colour will be converted to RGB before subtraction. This conversion depends upon a #to_rgb method on the other colour.
The subtraction is done using the RGB Accessor methods to ensure a valid colour in the result.
542 543 544 |
# File 'lib/color/rgb.rb', line 542 def -(other) self + (-other) end |
#-@ ⇒ Object
Numerically negate the color. This results in a color that is only usable for subtraction.
563 564 565 566 567 568 569 |
# File 'lib/color/rgb.rb', line 563 def -@ rgb = self.dup rgb.instance_variable_set(:@r, -rgb.r) rgb.instance_variable_set(:@g, -rgb.g) rgb.instance_variable_set(:@b, -rgb.b) rgb end |
#adjust_brightness(percent) ⇒ Object
301 302 303 304 305 306 |
# File 'lib/color/rgb.rb', line 301 def adjust_brightness(percent) percent = normalize_percent(percent) hsl = to_hsl hsl.l *= percent hsl.to_rgb end |
#adjust_hue(percent) ⇒ Object
327 328 329 330 331 332 |
# File 'lib/color/rgb.rb', line 327 def adjust_hue(percent) percent = normalize_percent(percent) hsl = to_hsl hsl.h *= percent hsl.to_rgb end |
#adjust_saturation(percent) ⇒ Object
314 315 316 317 318 319 |
# File 'lib/color/rgb.rb', line 314 def adjust_saturation(percent) percent = normalize_percent(percent) hsl = to_hsl hsl.s *= percent hsl.to_rgb end |
#b ⇒ Object
Returns the blue component of the colour as a fraction in the range 0.0 .. 1.0.
509 510 511 |
# File 'lib/color/rgb.rb', line 509 def b @b end |
#b=(bb) ⇒ Object
Sets the blue component of the colour as a fraction in the range 0.0 .. 1.0.
522 523 524 |
# File 'lib/color/rgb.rb', line 522 def b=(bb) @b = Color.normalize(bb) end |
#blue ⇒ Object
Returns the blue component of the colour in the normal 0 .. 255 range.
500 501 502 |
# File 'lib/color/rgb.rb', line 500 def blue @b * 255.0 end |
#blue=(bb) ⇒ Object
Sets the blue component of the colour in the normal 0 .. 255 range.
513 514 515 |
# File 'lib/color/rgb.rb', line 513 def blue=(bb) @b = Color.normalize(bb / 255.0) end |
#blue_p ⇒ Object
Returns the blue component of the colour as a percentage.
504 505 506 |
# File 'lib/color/rgb.rb', line 504 def blue_p @b * 100.0 end |
#blue_p=(bb) ⇒ Object
Sets the blue component of the colour as a percentage.
517 518 519 |
# File 'lib/color/rgb.rb', line 517 def blue_p=(bb) @b = Color.normalize(bb / 100.0) end |
#brightness ⇒ Object
Returns the brightness value for a colour, a number between 0..1. Based on the Y value of YIQ encoding, representing luminosity, or perceived brightness.
This may be modified in a future version of color-tools to use the luminosity value of HSL.
286 287 288 |
# File 'lib/color/rgb.rb', line 286 def brightness to_yiq.y end |
#closest_match(color_list, threshold_distance = 1000.0) ⇒ Object
Calculates and returns the closest match to this colour from a list of provided colours. Returns nil
if color_list
is empty or if there is no colour within the threshold_distance
.
threshold_distance
is used to determine the minimum colour distance permitted. Uses the CIE Delta E 1994 algorithm (CIE94) to find near matches based on perceived visual colour. The default value (1000.0) is an arbitrarily large number. The values :jnd
and :just_noticeable
may be passed as the threshold_distance
to use the value 2.3
.
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 |
# File 'lib/color/rgb.rb', line 347 def closest_match(color_list, threshold_distance = 1000.0) color_list = [ color_list ].flatten(1) return nil if color_list.empty? threshold_distance = case threshold_distance when :jnd, :just_noticeable 2.3 else threshold_distance.to_f end lab = to_lab closest_distance = threshold_distance best_match = nil color_list.each do |c| distance = delta_e94(lab, c.to_lab) if (distance < closest_distance) closest_distance = distance best_match = c end end best_match end |
#coerce(other) ⇒ Object
Coerces the other Color object into RGB.
11 12 13 |
# File 'lib/color/rgb.rb', line 11 def coerce(other) other.to_rgb end |
#contrast(other) ⇒ Object
Outputs how much contrast this color has with another RGB color. Computes the same regardless of which one is considered foreground. If the other color does not have a #to_rgb method, this will throw an exception. Anything over about 0.22 should have a high likelihood of being legible, but the larger the difference, the more contrast. Otherwise, to be safe go with something > 0.3
10 11 12 13 14 15 16 17 |
# File 'lib/color/rgb/contrast.rb', line 10 def contrast(other) other = coerce(other) # The following numbers have been set with some care. ((diff_brightness(other) * 0.65) + (diff_hue(other) * 0.20) + (diff_luminosity(other) * 0.15)) end |
#css_hsl ⇒ Object
Present the colour as an HSL HTML/CSS colour string (e.g., “hsl(180, 25%, 35%)”). Note that this will perform a #to_hsl operation using the default conversion formula.
77 78 79 |
# File 'lib/color/rgb.rb', line 77 def css_hsl to_hsl.css_hsl end |
#css_hsla ⇒ Object
Present the colour as an HSLA (with alpha) HTML/CSS colour string (e.g., “hsla(180, 25%, 35%, 1)”). Note that this will perform a #to_hsl operation using the default conversion formula.
84 85 86 |
# File 'lib/color/rgb.rb', line 84 def css_hsla to_hsl.css_hsla end |
#css_rgb ⇒ Object
Present the colour as an RGB HTML/CSS colour string (e.g., “rgb(0%, 50%, 100%)”). Note that this will perform a #to_rgb operation using the default conversion formula.
58 59 60 |
# File 'lib/color/rgb.rb', line 58 def css_rgb "rgb(%3.2f%%, %3.2f%%, %3.2f%%)" % [ red_p, green_p, blue_p ] end |
#css_rgba(alpha = 1) ⇒ Object
Present the colour as an RGBA (with an optional alpha that defaults to 1) HTML/CSS colour string (e.g.,“rgb(0%, 50%, 100%, 1)”). Note that this will perform a #to_rgb operation using the default conversion formula.
Color::RGB.by_hex('ff0000').css_rgba
=> 'rgba(100.00%, 0.00%, 0.00%, 1.00)'
Color::RGB.by_hex('ff0000').css_rgba(0.2)
=> 'rgba(100.00%, 0.00%, 0.00%, 0.20)'
70 71 72 |
# File 'lib/color/rgb.rb', line 70 def css_rgba(alpha = 1) "rgba(%3.2f%%, %3.2f%%, %3.2f%%, %3.2f)" % [ red_p, green_p, blue_p, alpha ] end |
#darken_by(percent) ⇒ Object
Mix the RGB hue with Black so that the RGB hue is the specified percentage of the resulting colour. Strictly speaking, this isn’t a darken_by operation.
263 264 265 |
# File 'lib/color/rgb.rb', line 263 def darken_by(percent) mix_with(Black, percent) end |
#delta_e94(color_1, color_2, weighting_type = :graphic_arts) ⇒ Object
The Delta E (CIE94) algorithm en.wikipedia.org/wiki/Color_difference#CIE94
There is a newer version, CIEDE2000, that uses slightly more complicated math, but addresses “the perceptual uniformity issue” left lingering by the CIE94 algorithm. color_1 and color_2 are both L*a*b* hashes, rendered by #to_lab.
Since our source is treated as sRGB, we use the “graphic arts” presets for k_L, k_1, and k_2
The calculations go through LCH(ab). (?)
See also www.brucelindbloom.com/index.html?Eqn_DeltaE_CIE94.html
NOTE: This should be moved to Color::Lab.
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 |
# File 'lib/color/rgb.rb', line 387 def delta_e94(color_1, color_2, weighting_type = :graphic_arts) case weighting_type when :graphic_arts k_1 = 0.045 k_2 = 0.015 k_L = 1 when :textiles k_1 = 0.048 k_2 = 0.014 k_L = 2 else raise ArgumentError, "Unsupported weighting type #{weighting_type}." end # delta_E = Math.sqrt( # ((delta_L / (k_L * s_L)) ** 2) + # ((delta_C / (k_C * s_C)) ** 2) + # ((delta_H / (k_H * s_H)) ** 2) # ) # # Under some circumstances in real computers, delta_H could be an # imaginary number (it's a square root value), so we're going to treat # this as: # # delta_E = Math.sqrt( # ((delta_L / (k_L * s_L)) ** 2) + # ((delta_C / (k_C * s_C)) ** 2) + # (delta_H2 / ((k_H * s_H) ** 2))) # ) # # And not perform the square root when calculating delta_H2. k_C = k_H = 1 l_1, a_1, b_1 = color_1.values_at(:L, :a, :b) l_2, a_2, b_2 = color_2.values_at(:L, :a, :b) delta_a = a_1 - a_2 delta_b = b_1 - b_2 c_1 = Math.sqrt((a_1 ** 2) + (b_1 ** 2)) c_2 = Math.sqrt((a_2 ** 2) + (b_2 ** 2)) delta_L = color_1[:L] - color_2[:L] delta_C = c_1 - c_2 delta_H2 = (delta_a ** 2) + (delta_b ** 2) - (delta_C ** 2) s_L = 1 s_C = 1 + k_1 * c_1 s_H = 1 + k_2 * c_1 composite_L = (delta_L / (k_L * s_L)) ** 2 composite_C = (delta_C / (k_C * s_C)) ** 2 composite_H = delta_H2 / ((k_H * s_H) ** 2) Math.sqrt(composite_L + composite_C + composite_H) end |
#g ⇒ Object
Returns the green component of the colour as a fraction in the range 0.0 .. 1.0.
482 483 484 |
# File 'lib/color/rgb.rb', line 482 def g @g end |
#g=(gg) ⇒ Object
Sets the green component of the colour as a fraction in the range 0.0 .. 1.0.
495 496 497 |
# File 'lib/color/rgb.rb', line 495 def g=(gg) @g = Color.normalize(gg) end |
#green ⇒ Object
Returns the green component of the colour in the normal 0 .. 255 range.
473 474 475 |
# File 'lib/color/rgb.rb', line 473 def green @g * 255.0 end |
#green=(gg) ⇒ Object
Sets the green component of the colour in the normal 0 .. 255 range.
486 487 488 |
# File 'lib/color/rgb.rb', line 486 def green=(gg) @g = Color.normalize(gg / 255.0) end |
#green_p ⇒ Object
Returns the green component of the colour as a percentage.
477 478 479 |
# File 'lib/color/rgb.rb', line 477 def green_p @g * 100.0 end |
#green_p=(gg) ⇒ Object
Sets the green component of the colour as a percentage.
490 491 492 |
# File 'lib/color/rgb.rb', line 490 def green_p=(gg) @g = Color.normalize(gg / 100.0) end |
#hex ⇒ Object
Present the colour as an RGB hex triplet.
37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/color/rgb.rb', line 37 def hex r = (@r * 255).round r = 255 if r > 255 g = (@g * 255).round g = 255 if g > 255 b = (@b * 255).round b = 255 if b > 255 "%02x%02x%02x" % [ r, g, b ] end |
#html ⇒ Object
Present the colour as an HTML/CSS colour string.
51 52 53 |
# File 'lib/color/rgb.rb', line 51 def html "##{hex}" end |
#inspect ⇒ Object
553 554 555 |
# File 'lib/color/rgb.rb', line 553 def inspect "RGB [#{html}]" end |
#lighten_by(percent) ⇒ Object
Mix the RGB hue with White so that the RGB hue is the specified percentage of the resulting colour. Strictly speaking, this isn’t a darken_by operation.
256 257 258 |
# File 'lib/color/rgb.rb', line 256 def lighten_by(percent) mix_with(White, percent) end |
#max_rgb_as_grayscale ⇒ Object Also known as: max_rgb_as_greyscale
Retrieve the maxmum RGB value from the current colour as a GrayScale colour
548 549 550 |
# File 'lib/color/rgb.rb', line 548 def max_rgb_as_grayscale Color::GrayScale.from_fraction([@r, @g, @b].max) end |
#mix_with(mask, opacity) ⇒ Object
Mix the mask colour (which must be an RGB object) with the current colour at the stated opacity percentage (0..100).
269 270 271 272 273 274 275 276 277 278 |
# File 'lib/color/rgb.rb', line 269 def mix_with(mask, opacity) opacity /= 100.0 rgb = self.dup rgb.r = (@r * opacity) + (mask.r * (1 - opacity)) rgb.g = (@g * opacity) + (mask.g * (1 - opacity)) rgb.b = (@b * opacity) + (mask.b * (1 - opacity)) rgb end |
#pdf_fill ⇒ Object
Present the colour as a DeviceRGB fill colour string for PDF. This will be removed from the default package in color-tools 2.0.
26 27 28 |
# File 'lib/color/rgb.rb', line 26 def pdf_fill PDF_FORMAT_STR % [ @r, @g, @b, "rg" ] end |
#pdf_stroke ⇒ Object
Present the colour as a DeviceRGB stroke colour string for PDF. This will be removed from the default package in color-tools 2.0.
32 33 34 |
# File 'lib/color/rgb.rb', line 32 def pdf_stroke PDF_FORMAT_STR % [ @r, @g, @b, "RG" ] end |
#r ⇒ Object
Returns the red component of the colour as a fraction in the range 0.0 .. 1.0.
455 456 457 |
# File 'lib/color/rgb.rb', line 455 def r @r end |
#r=(rr) ⇒ Object
Sets the red component of the colour as a fraction in the range 0.0 .. 1.0.
468 469 470 |
# File 'lib/color/rgb.rb', line 468 def r=(rr) @r = Color.normalize(rr) end |
#red ⇒ Object
Returns the red component of the colour in the normal 0 .. 255 range.
446 447 448 |
# File 'lib/color/rgb.rb', line 446 def red @r * 255.0 end |
#red=(rr) ⇒ Object
Sets the red component of the colour in the normal 0 .. 255 range.
459 460 461 |
# File 'lib/color/rgb.rb', line 459 def red=(rr) @r = Color.normalize(rr / 255.0) end |
#red_p ⇒ Object
Returns the red component of the colour as a percentage.
450 451 452 |
# File 'lib/color/rgb.rb', line 450 def red_p @r * 100.0 end |
#red_p=(rr) ⇒ Object
Sets the red component of the colour as a percentage.
463 464 465 |
# File 'lib/color/rgb.rb', line 463 def red_p=(rr) @r = Color.normalize(rr / 100.0) end |
#to_a ⇒ Object
557 558 559 |
# File 'lib/color/rgb.rb', line 557 def to_a [ r, g, b ] end |
#to_cmyk ⇒ Object
Converts the RGB colour to CMYK. Most colour experts strongly suggest that this is not a good idea (some even suggesting that it’s a very bad idea). CMYK represents additive percentages of inks on white paper, whereas RGB represents mixed colour intensities on a black screen.
However, the colour conversion can be done. The basic method is multi-step:
-
Convert the R, G, and B components to C, M, and Y components.
c = 1.0 - r m = 1.0 - g y = 1.0 - b
-
Compute the minimum amount of black (K) required to smooth the colour in inks.
k = min(c, m, y)
-
Perform undercolour removal on the C, M, and Y components of the colours because less of each colour is needed for each bit of black. Also, regenerate the black (K) based on the undercolour removal so that the colour is more accurately represented in ink.
c = min(1.0, max(0.0, c - UCR(k))) m = min(1.0, max(0.0, m - UCR(k))) y = min(1.0, max(0.0, y - UCR(k))) k = min(1.0, max(0.0, BG(k)))
The undercolour removal function and the black generation functions return a value based on the brightness of the RGB colour.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# File 'lib/color/rgb.rb', line 114 def to_cmyk c = 1.0 - @r.to_f m = 1.0 - @g.to_f y = 1.0 - @b.to_f k = [c, m, y].min k = k - (k * brightness) c = [1.0, [0.0, c - k].max].min m = [1.0, [0.0, m - k].max].min y = [1.0, [0.0, y - k].max].min k = [1.0, [0.0, k].max].min Color::CMYK.from_fraction(c, m, y, k) end |
#to_grayscale ⇒ Object Also known as: to_greyscale
Convert to grayscale.
290 291 292 |
# File 'lib/color/rgb.rb', line 290 def to_grayscale Color::GrayScale.from_fraction(to_hsl.l) end |
#to_hsl ⇒ Object
Returns the HSL colour encoding of the RGB value. The conversions here are based on forumlas from www.easyrgb.com/math.php and elsewhere.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/color/rgb.rb', line 145 def to_hsl min = [ @r, @g, @b ].min max = [ @r, @g, @b ].max delta = (max - min).to_f lum = (max + min) / 2.0 if Color.near_zero?(delta) # close to 0.0, so it's a grey hue = 0 sat = 0 else if Color.near_zero_or_less?(lum - 0.5) sat = delta / (max + min).to_f else sat = delta / (2 - max - min).to_f end # This is based on the conversion algorithm from # http://en.wikipedia.org/wiki/HSV_color_space#Conversion_from_RGB_to_HSL_or_HSV # Contributed by Adam Johnson sixth = 1 / 6.0 if @r == max # Color.near_zero_or_less?(@r - max) hue = (sixth * ((@g - @b) / delta)) hue += 1.0 if @g < @b elsif @g == max # Color.near_zero_or_less(@g - max) hue = (sixth * ((@b - @r) / delta)) + (1.0 / 3.0) elsif @b == max # Color.near_zero_or_less?(@b - max) hue = (sixth * ((@r - @g) / delta)) + (2.0 / 3.0) end hue += 1 if hue < 0 hue -= 1 if hue > 1 end Color::HSL.from_fraction(hue, sat, lum) end |
#to_lab(color_space = :sRGB, reference_white = [ 95.047, 100.00, 108.883 ]) ⇒ Object
Returns the L*a*b* colour encoding of the value via the XYZ colour encoding. Based on the XYZ to Lab formula presented by Bruce Lindbloom.
Currently only the sRGB colour space is supported and defaults to using a D65 reference white.
217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 |
# File 'lib/color/rgb.rb', line 217 def to_lab(color_space = :sRGB, reference_white = [ 95.047, 100.00, 108.883 ]) xyz = to_xyz # Calculate the ratio of the XYZ values to the reference white. # http://www.brucelindbloom.com/index.html?Equations.html xr = xyz[:x] / reference_white[0] yr = xyz[:y] / reference_white[1] zr = xyz[:z] / reference_white[2] # NOTE: This should be using Rational instead of floating point values, # otherwise there will be discontinuities. # http://www.brucelindbloom.com/LContinuity.html epsilon = (216 / 24389.0) kappa = (24389 / 27.0) # And now transform # http://en.wikipedia.org/wiki/Lab_color_space#Forward_transformation # There is a brief explanation there as far as the nature of the calculations, # as well as a much nicer looking modeling of the algebra. fx, fy, fz = [ xr, yr, zr ].map { |t| if (t > (epsilon)) t ** (1.0 / 3) else # t <= epsilon ((kappa * t) + 16) / 116.0 # The 4/29 here is for when t = 0 (black). 4/29 * 116 = 16, and 16 - # 16 = 0, which is the correct value for L* with black. # ((1.0/3)*((29.0/6)**2) * t) + (4.0/29) end } { :L => ((116 * fy) - 16), :a => (500 * (fx - fy)), :b => (200 * (fy - fz)) } end |
#to_rgb(ignored = nil) ⇒ Object
130 131 132 |
# File 'lib/color/rgb.rb', line 130 def to_rgb(ignored = nil) self end |
#to_xyz(color_space = :sRGB) ⇒ Object
Returns the XYZ colour encoding of the value. Based on the RGB to XYZ formula presented by Bruce Lindbloom.
Currently only the sRGB colour space is supported.
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
# File 'lib/color/rgb.rb', line 186 def to_xyz(color_space = :sRGB) unless color_space.to_s.downcase == 'srgb' raise ArgumentError, "Unsupported colour space #{color_space}." end # Inverse sRGB companding. Linearizes RGB channels with respect to # energy. r, g, b = [ @r, @g, @b ].map { |v| if (v > 0.04045) (((v + 0.055) / 1.055) ** 2.4) * 100 else (v / 12.92) * 100 end } # Convert using the RGB/XYZ matrix at: # http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html#WSMatrices { :x => (r * 0.4124564 + g * 0.3575761 + b * 0.1804375), :y => (r * 0.2126729 + g * 0.7151522 + b * 0.0721750), :z => (r * 0.0193339 + g * 0.1191920 + b * 0.9503041) } end |
#to_yiq ⇒ Object
Returns the YIQ (NTSC) colour encoding of the RGB value.
135 136 137 138 139 140 |
# File 'lib/color/rgb.rb', line 135 def to_yiq y = (@r * 0.299) + (@g * 0.587) + (@b * 0.114) i = (@r * 0.596) + (@g * -0.275) + (@b * -0.321) q = (@r * 0.212) + (@g * -0.523) + (@b * 0.311) Color::YIQ.from_fraction(y, i, q) end |