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 ⇒ Object
Present the colour as an RGBA (with alpha) 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.
643 644 645 |
# File 'lib/color/rgb.rb', line 643 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.
627 628 629 630 631 632 633 634 635 |
# File 'lib/color/rgb.rb', line 627 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.
638 639 640 |
# File 'lib/color/rgb.rb', line 638 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.
648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 |
# File 'lib/color/rgb.rb', line 648 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)
587 588 589 |
# File 'lib/color/rgb.rb', line 587 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.
592 593 594 |
# File 'lib/color/rgb.rb', line 592 def from_grayscale_fraction(l = 0.0, &block) new(l, l, l, 1.0, &block) end |
.from_html(html_colour, &block) ⇒ Object
604 605 606 607 608 609 610 611 612 613 614 615 |
# File 'lib/color/rgb.rb', line 604 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.
527 528 529 |
# File 'lib/color/rgb.rb', line 527 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.
537 538 539 |
# File 'lib/color/rgb.rb', line 537 def -(other) self + (-other) end |
#-@ ⇒ Object
Numerically negate the color. This results in a color that is only usable for subtraction.
558 559 560 561 562 563 564 |
# File 'lib/color/rgb.rb', line 558 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
296 297 298 299 300 301 |
# File 'lib/color/rgb.rb', line 296 def adjust_brightness(percent) percent = normalize_percent(percent) hsl = to_hsl hsl.l *= percent hsl.to_rgb end |
#adjust_hue(percent) ⇒ Object
322 323 324 325 326 327 |
# File 'lib/color/rgb.rb', line 322 def adjust_hue(percent) percent = normalize_percent(percent) hsl = to_hsl hsl.h *= percent hsl.to_rgb end |
#adjust_saturation(percent) ⇒ Object
309 310 311 312 313 314 |
# File 'lib/color/rgb.rb', line 309 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.
504 505 506 |
# File 'lib/color/rgb.rb', line 504 def b @b end |
#b=(bb) ⇒ Object
Sets the blue component of the colour as a fraction in the range 0.0 .. 1.0.
517 518 519 |
# File 'lib/color/rgb.rb', line 517 def b=(bb) @b = Color.normalize(bb) end |
#blue ⇒ Object
Returns the blue component of the colour in the normal 0 .. 255 range.
495 496 497 |
# File 'lib/color/rgb.rb', line 495 def blue @b * 255.0 end |
#blue=(bb) ⇒ Object
Sets the blue component of the colour in the normal 0 .. 255 range.
508 509 510 |
# File 'lib/color/rgb.rb', line 508 def blue=(bb) @b = Color.normalize(bb / 255.0) end |
#blue_p ⇒ Object
Returns the blue component of the colour as a percentage.
499 500 501 |
# File 'lib/color/rgb.rb', line 499 def blue_p @b * 100.0 end |
#blue_p=(bb) ⇒ Object
Sets the blue component of the colour as a percentage.
512 513 514 |
# File 'lib/color/rgb.rb', line 512 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.
281 282 283 |
# File 'lib/color/rgb.rb', line 281 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
.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 |
# File 'lib/color/rgb.rb', line 342 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.
72 73 74 |
# File 'lib/color/rgb.rb', line 72 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.
79 80 81 |
# File 'lib/color/rgb.rb', line 79 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 ⇒ Object
Present the colour as an RGBA (with alpha) 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.
65 66 67 |
# File 'lib/color/rgb.rb', line 65 def css_rgba "rgba(%3.2f%%, %3.2f%%, %3.2f%%, %3.2f)" % [ red_p, green_p, blue_p, 1 ] 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.
258 259 260 |
# File 'lib/color/rgb.rb', line 258 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.
382 383 384 385 386 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 |
# File 'lib/color/rgb.rb', line 382 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.
477 478 479 |
# File 'lib/color/rgb.rb', line 477 def g @g end |
#g=(gg) ⇒ Object
Sets the green component of the colour as a fraction in the range 0.0 .. 1.0.
490 491 492 |
# File 'lib/color/rgb.rb', line 490 def g=(gg) @g = Color.normalize(gg) end |
#green ⇒ Object
Returns the green component of the colour in the normal 0 .. 255 range.
468 469 470 |
# File 'lib/color/rgb.rb', line 468 def green @g * 255.0 end |
#green=(gg) ⇒ Object
Sets the green component of the colour in the normal 0 .. 255 range.
481 482 483 |
# File 'lib/color/rgb.rb', line 481 def green=(gg) @g = Color.normalize(gg / 255.0) end |
#green_p ⇒ Object
Returns the green component of the colour as a percentage.
472 473 474 |
# File 'lib/color/rgb.rb', line 472 def green_p @g * 100.0 end |
#green_p=(gg) ⇒ Object
Sets the green component of the colour as a percentage.
485 486 487 |
# File 'lib/color/rgb.rb', line 485 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
548 549 550 |
# File 'lib/color/rgb.rb', line 548 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.
251 252 253 |
# File 'lib/color/rgb.rb', line 251 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
543 544 545 |
# File 'lib/color/rgb.rb', line 543 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).
264 265 266 267 268 269 270 271 272 273 |
# File 'lib/color/rgb.rb', line 264 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.
450 451 452 |
# File 'lib/color/rgb.rb', line 450 def r @r end |
#r=(rr) ⇒ Object
Sets the red component of the colour as a fraction in the range 0.0 .. 1.0.
463 464 465 |
# File 'lib/color/rgb.rb', line 463 def r=(rr) @r = Color.normalize(rr) end |
#red ⇒ Object
Returns the red component of the colour in the normal 0 .. 255 range.
441 442 443 |
# File 'lib/color/rgb.rb', line 441 def red @r * 255.0 end |
#red=(rr) ⇒ Object
Sets the red component of the colour in the normal 0 .. 255 range.
454 455 456 |
# File 'lib/color/rgb.rb', line 454 def red=(rr) @r = Color.normalize(rr / 255.0) end |
#red_p ⇒ Object
Returns the red component of the colour as a percentage.
445 446 447 |
# File 'lib/color/rgb.rb', line 445 def red_p @r * 100.0 end |
#red_p=(rr) ⇒ Object
Sets the red component of the colour as a percentage.
458 459 460 |
# File 'lib/color/rgb.rb', line 458 def red_p=(rr) @r = Color.normalize(rr / 100.0) end |
#to_a ⇒ Object
552 553 554 |
# File 'lib/color/rgb.rb', line 552 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.
109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/color/rgb.rb', line 109 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.
285 286 287 |
# File 'lib/color/rgb.rb', line 285 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.
140 141 142 143 144 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 |
# File 'lib/color/rgb.rb', line 140 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.
212 213 214 215 216 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 |
# File 'lib/color/rgb.rb', line 212 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
125 126 127 |
# File 'lib/color/rgb.rb', line 125 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.
181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/color/rgb.rb', line 181 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.
130 131 132 133 134 135 |
# File 'lib/color/rgb.rb', line 130 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 |