Module: ChunkyPNG::Color
Overview
The Color module defines methods for handling colors. Within the ChunkyPNG library, the concepts of pixels and colors are both used, and they are both represented by a Integer.
Pixels/colors are represented in RGBA components. Each of the four components is stored with a depth of 8 bits (maximum value = 255 = MAX). Together, these components are stored in a 4-byte Integer.
A color will always be represented using these 4 components in memory. When the image is encoded, a more suitable representation can be used (e.g. rgb, grayscale, palette-based), for which several conversion methods are provided in this module.
Constant Summary collapse
- MAX =
Returns The maximum value of each color component.
0xff
- MAX_EUCLIDEAN_DISTANCE_RGBA =
Could be simplified as MAX * 2, but this format mirrors the math in #euclidean_distance_rgba
Math.sqrt(MAX**2 * 4)
- PREDEFINED_COLORS =
Returns All the predefined color names in HTML.
{ :aliceblue => 0xf0f8ff00, :antiquewhite => 0xfaebd700, :aqua => 0x00ffff00, :aquamarine => 0x7fffd400, :azure => 0xf0ffff00, :beige => 0xf5f5dc00, :bisque => 0xffe4c400, :black => 0x00000000, :blanchedalmond => 0xffebcd00, :blue => 0x0000ff00, :blueviolet => 0x8a2be200, :brown => 0xa52a2a00, :burlywood => 0xdeb88700, :cadetblue => 0x5f9ea000, :chartreuse => 0x7fff0000, :chocolate => 0xd2691e00, :coral => 0xff7f5000, :cornflowerblue => 0x6495ed00, :cornsilk => 0xfff8dc00, :crimson => 0xdc143c00, :cyan => 0x00ffff00, :darkblue => 0x00008b00, :darkcyan => 0x008b8b00, :darkgoldenrod => 0xb8860b00, :darkgray => 0xa9a9a900, :darkgrey => 0xa9a9a900, :darkgreen => 0x00640000, :darkkhaki => 0xbdb76b00, :darkmagenta => 0x8b008b00, :darkolivegreen => 0x556b2f00, :darkorange => 0xff8c0000, :darkorchid => 0x9932cc00, :darkred => 0x8b000000, :darksalmon => 0xe9967a00, :darkseagreen => 0x8fbc8f00, :darkslateblue => 0x483d8b00, :darkslategray => 0x2f4f4f00, :darkslategrey => 0x2f4f4f00, :darkturquoise => 0x00ced100, :darkviolet => 0x9400d300, :deeppink => 0xff149300, :deepskyblue => 0x00bfff00, :dimgray => 0x69696900, :dimgrey => 0x69696900, :dodgerblue => 0x1e90ff00, :firebrick => 0xb2222200, :floralwhite => 0xfffaf000, :forestgreen => 0x228b2200, :fuchsia => 0xff00ff00, :gainsboro => 0xdcdcdc00, :ghostwhite => 0xf8f8ff00, :gold => 0xffd70000, :goldenrod => 0xdaa52000, :gray => 0x80808000, :grey => 0x80808000, :green => 0x00800000, :greenyellow => 0xadff2f00, :honeydew => 0xf0fff000, :hotpink => 0xff69b400, :indianred => 0xcd5c5c00, :indigo => 0x4b008200, :ivory => 0xfffff000, :khaki => 0xf0e68c00, :lavender => 0xe6e6fa00, :lavenderblush => 0xfff0f500, :lawngreen => 0x7cfc0000, :lemonchiffon => 0xfffacd00, :lightblue => 0xadd8e600, :lightcoral => 0xf0808000, :lightcyan => 0xe0ffff00, :lightgoldenrodyellow => 0xfafad200, :lightgray => 0xd3d3d300, :lightgrey => 0xd3d3d300, :lightgreen => 0x90ee9000, :lightpink => 0xffb6c100, :lightsalmon => 0xffa07a00, :lightseagreen => 0x20b2aa00, :lightskyblue => 0x87cefa00, :lightslategray => 0x77889900, :lightslategrey => 0x77889900, :lightsteelblue => 0xb0c4de00, :lightyellow => 0xffffe000, :lime => 0x00ff0000, :limegreen => 0x32cd3200, :linen => 0xfaf0e600, :magenta => 0xff00ff00, :maroon => 0x80000000, :mediumaquamarine => 0x66cdaa00, :mediumblue => 0x0000cd00, :mediumorchid => 0xba55d300, :mediumpurple => 0x9370d800, :mediumseagreen => 0x3cb37100, :mediumslateblue => 0x7b68ee00, :mediumspringgreen => 0x00fa9a00, :mediumturquoise => 0x48d1cc00, :mediumvioletred => 0xc7158500, :midnightblue => 0x19197000, :mintcream => 0xf5fffa00, :mistyrose => 0xffe4e100, :moccasin => 0xffe4b500, :navajowhite => 0xffdead00, :navy => 0x00008000, :oldlace => 0xfdf5e600, :olive => 0x80800000, :olivedrab => 0x6b8e2300, :orange => 0xffa50000, :orangered => 0xff450000, :orchid => 0xda70d600, :palegoldenrod => 0xeee8aa00, :palegreen => 0x98fb9800, :paleturquoise => 0xafeeee00, :palevioletred => 0xd8709300, :papayawhip => 0xffefd500, :peachpuff => 0xffdab900, :peru => 0xcd853f00, :pink => 0xffc0cb00, :plum => 0xdda0dd00, :powderblue => 0xb0e0e600, :purple => 0x80008000, :red => 0xff000000, :rosybrown => 0xbc8f8f00, :royalblue => 0x4169e100, :saddlebrown => 0x8b451300, :salmon => 0xfa807200, :sandybrown => 0xf4a46000, :seagreen => 0x2e8b5700, :seashell => 0xfff5ee00, :sienna => 0xa0522d00, :silver => 0xc0c0c000, :skyblue => 0x87ceeb00, :slateblue => 0x6a5acd00, :slategray => 0x70809000, :slategrey => 0x70809000, :snow => 0xfffafa00, :springgreen => 0x00ff7f00, :steelblue => 0x4682b400, :tan => 0xd2b48c00, :teal => 0x00808000, :thistle => 0xd8bfd800, :tomato => 0xff634700, :turquoise => 0x40e0d000, :violet => 0xee82ee00, :wheat => 0xf5deb300, :white => 0xffffff00, :whitesmoke => 0xf5f5f500, :yellow => 0xffff0000, :yellowgreen => 0x9acd3200 }
- BLACK =
Returns Black pixel/color.
rgb( 0, 0, 0)
- WHITE =
Returns White pixel/color.
rgb(255, 255, 255)
- TRANSPARENT =
Returns Fully transparent pixel/color.
rgba(0, 0, 0, 0)
Instance Method Summary collapse
-
#a(value) ⇒ Integer
Returns the alpha channel value for the color value.
-
#alpha_decomposable?(color, mask, bg, tolerance = 1) ⇒ Boolean
Checks whether an alpha channel value can successfully be composed given the resulting color, the mask color and a background color, all of which should be opaque.
-
#b(value) ⇒ Integer
Returns the blue-component from the color value.
-
#blend(fg, bg) ⇒ Integer
Blends the foreground and background color by taking the average of the components.
-
#compose_precise(fg, bg) ⇒ Integer
Composes two colors with an alpha channel using floating point math.
-
#compose_quick(fg, bg) ⇒ Integer
(also: #compose)
Composes two colors with an alpha channel using integer math.
-
#decompose_alpha(color, mask, bg) ⇒ Integer
Decomposes the alpha channel value given the resulting color, the mask color and a background color, all of which should be opaque.
-
#decompose_alpha_component(channel, color, mask, bg) ⇒ Integer
Decomposes an alpha channel for either the r, g or b color channel.
-
#decompose_alpha_components(color, mask, bg) ⇒ Array<Integer>
Decomposes the alpha channels for the r, g and b color channel.
-
#decompose_color(color, mask, bg, tolerance = 1) ⇒ Integer
Decomposes a color, given a color, a mask color and a background color.
-
#euclidean_distance_rgba(pixel_after, pixel_before) ⇒ Float
Compute the Euclidean distance between 2 colors in RGBA.
-
#fade(color, factor) ⇒ Integer
Lowers the intensity of a color, by lowering its alpha by a given factor.
-
#from_hex(hex_value, opacity = nil) ⇒ Integer
Creates a color by converting it from a string in hex notation.
-
#from_hsl(hue, saturation, lightness, alpha = 255) ⇒ Integer
Creates a new color from an HSL triple.
-
#from_hsv(hue, saturation, value, alpha = 255) ⇒ Integer
(also: #from_hsb)
Creates a new color from an HSV triple.
-
#from_rgb_stream(stream, pos = 0) ⇒ Integer
Creates a color by unpacking an rgb triple from a string.
-
#from_rgba_stream(stream, pos = 0) ⇒ Integer
Creates a color by unpacking an rgba triple from a string.
-
#fully_transparent?(value) ⇒ true, false
Returns true if this color is fully transparent.
-
#g(value) ⇒ Integer
Returns the green-component from the color value.
-
#grayscale(teint) ⇒ Integer
Creates a new color using a grayscale teint.
-
#grayscale?(value) ⇒ true, false
Returns true if this color is fully transparent.
-
#grayscale_alpha(teint, a) ⇒ Integer
Creates a new color using a grayscale teint and alpha value.
-
#grayscale_teint(color) ⇒ Integer
Calculates the grayscale teint of an RGB color.
-
#html_color(color_name, opacity = nil) ⇒ Integer
Gets a color value based on a HTML color name.
-
#int8_mult(a, b) ⇒ Integer
Multiplies two fractions using integer math, where the fractions are stored using an integer between 0 and 255.
-
#interpolate_quick(fg, bg, alpha) ⇒ Object
Interpolates the foreground and background colors by the given alpha value.
-
#opaque!(value) ⇒ Integer
Returns the opaque value of this color by removing the alpha channel.
-
#opaque?(value) ⇒ true, false
Returns true if this color is fully opaque.
-
#parse(source) ⇒ Integer
Parses a color value given a numeric or string argument.
-
#pass_bytesize(color_mode, depth, width, height) ⇒ Integer
Returns the number of bytes used for an image pass.
-
#pixel_bitsize(color_mode, depth = 8) ⇒ Integer
Returns the size in bits of a pixel when it is stored using a given color mode.
-
#pixel_bytesize(color_mode, depth = 8) ⇒ Integer
Returns the size in bytes of a pixel when it is stored using a given color mode.
-
#r(value) ⇒ Integer
Returns the red-component from the color value.
-
#rgb(r, g, b) ⇒ Integer
Creates a new color using an r, g, b triple.
-
#rgba(r, g, b, a) ⇒ Integer
Creates a new color using an r, g, b triple and an alpha value.
-
#samples_per_pixel(color_mode) ⇒ Integer
Returns the number of sample values per pixel.
-
#scanline_bytesize(color_mode, depth, width) ⇒ Integer
Returns the number of bytes used per scanline.
-
#to_grayscale(color) ⇒ Integer
Converts a color to a fiting grayscale value.
-
#to_grayscale_alpha_bytes(color) ⇒ Array<Integer>
Returns an array with the grayscale teint and alpha channel values for this color.
-
#to_grayscale_bytes(color) ⇒ Array<Integer>
Returns an array with the grayscale teint value for this color.
-
#to_hex(color, include_alpha = true) ⇒ String
Returns a string representing this color using hex notation (i.e. #rrggbbaa).
-
#to_hsl(color, include_alpha = false) ⇒ Array<Fixnum>[0], ...
Returns an array with the separate HSL components of a color.
-
#to_hsv(color, include_alpha = false) ⇒ Array[0], ...
(also: #to_hsb)
Returns an array with the separate HSV components of a color.
-
#to_truecolor_alpha_bytes(color) ⇒ Array<Integer>
Returns an array with the separate RGBA values for this color.
-
#to_truecolor_bytes(color) ⇒ Array<Integer>
Returns an array with the separate RGB values for this color.
Instance Method Details
#a(value) ⇒ Integer
Returns the alpha channel value for the color value.
296 297 298 |
# File 'lib/chunky_png/color.rb', line 296 def a(value) value & 0x000000ff end |
#alpha_decomposable?(color, mask, bg, tolerance = 1) ⇒ Boolean
Checks whether an alpha channel value can successfully be composed given the resulting color, the mask color and a background color, all of which should be opaque.
500 501 502 503 504 505 |
# File 'lib/chunky_png/color.rb', line 500 def alpha_decomposable?(color, mask, bg, tolerance = 1) components = decompose_alpha_components(color, mask, bg) sum = components.inject(0) { |a,b| a + b } max = components.max * 3 components.max <= 255 && components.min >= 0 && (sum + tolerance * 3) >= max end |
#b(value) ⇒ Integer
Returns the blue-component from the color value.
288 289 290 |
# File 'lib/chunky_png/color.rb', line 288 def b(value) (value & 0x0000ff00) >> 8 end |
#blend(fg, bg) ⇒ Integer
Blends the foreground and background color by taking the average of the components.
403 404 405 |
# File 'lib/chunky_png/color.rb', line 403 def blend(fg, bg) (fg + bg) >> 1 end |
#compose_precise(fg, bg) ⇒ Integer
Composes two colors with an alpha channel using floating point math.
This method uses more precise floating point math, but this precision is lost when the result is converted back to an integer. Because it is slower than the version based on integer math, that version is preferred.
380 381 382 383 384 385 386 387 388 389 390 391 392 393 |
# File 'lib/chunky_png/color.rb', line 380 def compose_precise(fg, bg) return fg if opaque?(fg) || fully_transparent?(bg) return bg if fully_transparent?(fg) fg_a = a(fg).to_f / MAX bg_a = a(bg).to_f / MAX a_com = (1.0 - fg_a) * bg_a new_r = (fg_a * r(fg) + a_com * r(bg)).round new_g = (fg_a * g(fg) + a_com * g(bg)).round new_b = (fg_a * b(fg) + a_com * b(bg)).round new_a = ((fg_a + a_com) * MAX).round rgba(new_r, new_g, new_b, new_a) end |
#compose_quick(fg, bg) ⇒ Integer Also known as: compose
Composes two colors with an alpha channel using integer math.
This version is faster than the version based on floating point math, so this compositing function is used by default.
358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/chunky_png/color.rb', line 358 def compose_quick(fg, bg) return fg if opaque?(fg) || fully_transparent?(bg) return bg if fully_transparent?(fg) a_com = int8_mult(0xff - a(fg), a(bg)) new_r = int8_mult(a(fg), r(fg)) + int8_mult(a_com, r(bg)) new_g = int8_mult(a(fg), g(fg)) + int8_mult(a_com, g(bg)) new_b = int8_mult(a(fg), b(fg)) + int8_mult(a_com, b(bg)) new_a = a(fg) + a_com rgba(new_r, new_g, new_b, new_a) end |
#decompose_alpha(color, mask, bg) ⇒ Integer
Decomposes the alpha channel value given the resulting color, the mask color and a background color, all of which should be opaque.
Make sure to call #alpha_decomposable? first to see if the alpha channel value can successfully decomposed with a given tolerance, otherwise the return value of this method is undefined.
521 522 523 524 |
# File 'lib/chunky_png/color.rb', line 521 def decompose_alpha(color, mask, bg) components = decompose_alpha_components(color, mask, bg) (components.inject(0) { |a,b| a + b } / 3.0).round end |
#decompose_alpha_component(channel, color, mask, bg) ⇒ Integer
Decomposes an alpha channel for either the r, g or b color channel.
534 535 536 537 538 539 540 541 542 |
# File 'lib/chunky_png/color.rb', line 534 def decompose_alpha_component(channel, color, mask, bg) cc, mc, bc = send(channel, color), send(channel, mask), send(channel, bg) return 0x00 if bc == cc return 0xff if bc == mc return 0xff if cc == mc (((bc - cc).to_f / (bc - mc).to_f) * MAX).round end |
#decompose_alpha_components(color, mask, bg) ⇒ Array<Integer>
Decomposes the alpha channels for the r, g and b color channel.
551 552 553 554 555 556 557 |
# File 'lib/chunky_png/color.rb', line 551 def decompose_alpha_components(color, mask, bg) [ decompose_alpha_component(:r, color, mask, bg), decompose_alpha_component(:g, color, mask, bg), decompose_alpha_component(:b, color, mask, bg) ] end |
#decompose_color(color, mask, bg, tolerance = 1) ⇒ Integer
Decomposes a color, given a color, a mask color and a background color. The returned color will be a variant of the mask color, with the alpha channel set to the best fitting value. This basically is the reverse operation if alpha composition.
If the color cannot be decomposed, this method will return the fully transparent variant of the mask color.
479 480 481 482 483 484 485 |
# File 'lib/chunky_png/color.rb', line 479 def decompose_color(color, mask, bg, tolerance = 1) if alpha_decomposable?(color, mask, bg, tolerance) mask & 0xffffff00 | decompose_alpha(color, mask, bg) else mask & 0xffffff00 end end |
#euclidean_distance_rgba(pixel_after, pixel_before) ⇒ Float
Compute the Euclidean distance between 2 colors in RGBA
This method simply takes the Euclidean distance between the RGBA channels of 2 colors, which gives us a measure of how different the two colors are.
Although it would be more perceptually accurate to calculate a proper Delta E in Lab colorspace, this method should serve many use-cases while avoiding the overhead of converting RGBA to Lab.
716 717 718 719 720 721 722 723 |
# File 'lib/chunky_png/color.rb', line 716 def euclidean_distance_rgba(pixel_after, pixel_before) Math.sqrt( (r(pixel_after) - r(pixel_before))**2 + (g(pixel_after) - g(pixel_before))**2 + (b(pixel_after) - b(pixel_before))**2 + (a(pixel_after) - a(pixel_before))**2 ) end |
#fade(color, factor) ⇒ Integer
Lowers the intensity of a color, by lowering its alpha by a given factor.
458 459 460 461 |
# File 'lib/chunky_png/color.rb', line 458 def fade(color, factor) new_alpha = int8_mult(a(color), factor) (color & 0xffffff00) | new_alpha end |
#from_hex(hex_value, opacity = nil) ⇒ Integer
Creates a color by converting it from a string in hex notation.
It supports colors with (#rrggbbaa) or without (#rrggbb) alpha channel as well as the 3-digit short format (#rgb) for those without. Color strings may include the prefix “0x” or “#”.
166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/chunky_png/color.rb', line 166 def from_hex(hex_value, opacity = nil) base_color = case hex_value when HEX3_COLOR_REGEXP $1.gsub(/([0-9a-f])/i, '\1\1').hex << 8 when HEX6_COLOR_REGEXP $1.hex << 8 else raise ArgumentError, "Not a valid hex color notation: #{hex_value.inspect}!" end opacity ||= $2 ? $2.hex : 0xff base_color | opacity end |
#from_hsl(hue, saturation, lightness, alpha = 255) ⇒ Integer
Creates a new color from an HSL triple.
This implementation follows the modern convention of 0 degrees hue indicating red.
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/chunky_png/color.rb', line 217 def from_hsl(hue, saturation, lightness, alpha = 255) raise ArgumentError, "Hue #{hue} was not between 0 and 360" unless (0..360).include?(hue) raise ArgumentError, "Saturation #{saturation} was not between 0 and 1" unless (0..1).include?(saturation) raise ArgumentError, "Lightness #{lightness} was not between 0 and 1" unless (0..1).include?(lightness) chroma = (1 - (2 * lightness - 1).abs) * saturation rgb = cylindrical_to_cubic(hue, saturation, lightness, chroma) rgb.map! { |component| ((component + lightness - 0.5 * chroma) * 255).to_i } rgb << alpha self.rgba(*rgb) end |
#from_hsv(hue, saturation, value, alpha = 255) ⇒ Integer Also known as: from_hsb
Creates a new color from an HSV triple.
Create a new color using an HSV (sometimes also called HSB) triple. The words ‘value` and `brightness` are used interchangeably and synonymously in descriptions of this colorspace. This implementation follows the modern convention of 0 degrees hue indicating red.
193 194 195 196 197 198 199 200 201 202 |
# File 'lib/chunky_png/color.rb', line 193 def from_hsv(hue, saturation, value, alpha = 255) raise ArgumentError, "Hue must be between 0 and 360" unless (0..360).include?(hue) raise ArgumentError, "Saturation must be between 0 and 1" unless (0..1).include?(saturation) raise ArgumentError, "Value/brightness must be between 0 and 1" unless (0..1).include?(value) chroma = value * saturation rgb = cylindrical_to_cubic(hue, saturation, value, chroma) rgb.map! { |component| ((component + value - chroma) * 255).to_i } rgb << alpha self.rgba(*rgb) end |
#from_rgb_stream(stream, pos = 0) ⇒ Integer
Creates a color by unpacking an rgb triple from a string.
140 141 142 |
# File 'lib/chunky_png/color.rb', line 140 def from_rgb_stream(stream, pos = 0) rgb(*stream.unpack("@#{pos}C3")) end |
#from_rgba_stream(stream, pos = 0) ⇒ Integer
Creates a color by unpacking an rgba triple from a string
150 151 152 |
# File 'lib/chunky_png/color.rb', line 150 def from_rgba_stream(stream, pos = 0) rgba(*stream.unpack("@#{pos}C4")) end |
#fully_transparent?(value) ⇒ true, false
Returns true if this color is fully transparent.
327 328 329 |
# File 'lib/chunky_png/color.rb', line 327 def fully_transparent?(value) a(value) == 0x00000000 end |
#g(value) ⇒ Integer
Returns the green-component from the color value.
280 281 282 |
# File 'lib/chunky_png/color.rb', line 280 def g(value) (value & 0x00ff0000) >> 16 end |
#grayscale(teint) ⇒ Integer
Creates a new color using a grayscale teint.
117 118 119 |
# File 'lib/chunky_png/color.rb', line 117 def grayscale(teint) teint << 24 | teint << 16 | teint << 8 | 0xff end |
#grayscale?(value) ⇒ true, false
Returns true if this color is fully transparent.
319 320 321 |
# File 'lib/chunky_png/color.rb', line 319 def grayscale?(value) r(value) == b(value) && b(value) == g(value) end |
#grayscale_alpha(teint, a) ⇒ Integer
Creates a new color using a grayscale teint and alpha value.
126 127 128 |
# File 'lib/chunky_png/color.rb', line 126 def grayscale_alpha(teint, a) teint << 24 | teint << 16 | teint << 8 | a end |
#grayscale_teint(color) ⇒ Integer
Calculates the grayscale teint of an RGB color.
435 436 437 |
# File 'lib/chunky_png/color.rb', line 435 def grayscale_teint(color) (r(color) * 0.3 + g(color) * 0.59 + b(color) * 0.11).round end |
#html_color(color_name, opacity = nil) ⇒ Integer
Gets a color value based on a HTML color name.
The color name is flexible. E.g. 'yellowgreen'
, 'Yellow green'
, 'YellowGreen'
, 'YELLOW_GREEN'
and :yellow_green
will all return the same color value.
You can include a opacity level in the color name (e.g. 'red @ 0.5'
) or give an explicit opacity value as second argument. If no opacity value is given, the color will be fully opaque.
901 902 903 904 905 906 907 908 |
# File 'lib/chunky_png/color.rb', line 901 def html_color(color_name, opacity = nil) if color_name.to_s =~ HTML_COLOR_REGEXP opacity ||= $2 ? ($2.to_f * 255.0).round : 0xff base_color_name = $1.gsub(/[^a-z]+/i, '').downcase.to_sym return PREDEFINED_COLORS[base_color_name] | opacity if PREDEFINED_COLORS.has_key?(base_color_name) end raise ArgumentError, "Unknown color name #{color_name}!" end |
#int8_mult(a, b) ⇒ Integer
Multiplies two fractions using integer math, where the fractions are stored using an integer between 0 and 255. This method is used as a helper method for compositing colors using integer math.
This is a quicker implementation of ((a * b) / 255.0).round.
344 345 346 347 |
# File 'lib/chunky_png/color.rb', line 344 def int8_mult(a, b) t = a * b + 0x80 ((t >> 8) + t) >> 8 end |
#interpolate_quick(fg, bg, alpha) ⇒ Object
Interpolates the foreground and background colors by the given alpha value. This also blends the alpha channels themselves.
A blending factor of 255 will give entirely the foreground, while a blending factor of 0 will give the background.
417 418 419 420 421 422 423 424 425 426 427 428 429 |
# File 'lib/chunky_png/color.rb', line 417 def interpolate_quick(fg, bg, alpha) return fg if alpha >= 255 return bg if alpha <= 0 alpha_com = 255 - alpha new_r = int8_mult(alpha, r(fg)) + int8_mult(alpha_com, r(bg)) new_g = int8_mult(alpha, g(fg)) + int8_mult(alpha_com, g(bg)) new_b = int8_mult(alpha, b(fg)) + int8_mult(alpha_com, b(bg)) new_a = int8_mult(alpha, a(fg)) + int8_mult(alpha_com, a(bg)) rgba(new_r, new_g, new_b, new_a) end |
#opaque!(value) ⇒ Integer
Returns the opaque value of this color by removing the alpha channel.
311 312 313 |
# File 'lib/chunky_png/color.rb', line 311 def opaque!(value) value | 0x000000ff end |
#opaque?(value) ⇒ true, false
Returns true if this color is fully opaque.
304 305 306 |
# File 'lib/chunky_png/color.rb', line 304 def opaque?(value) a(value) == 0x000000ff end |
#parse(source) ⇒ Integer
Parses a color value given a numeric or string argument.
It supports color numbers, colors in hex notation and named HTML colors.
84 85 86 87 88 89 90 91 92 |
# File 'lib/chunky_png/color.rb', line 84 def parse(source) return source if source.kind_of?(Integer) case source.to_s when /^\d+$/; source.to_s.to_i when HEX3_COLOR_REGEXP, HEX6_COLOR_REGEXP; from_hex(source.to_s) when HTML_COLOR_REGEXP; html_color(source.to_s) else raise ArgumentError, "Don't know how to create a color from #{source.inspect}!" end end |
#pass_bytesize(color_mode, depth, width, height) ⇒ Integer
Returns the number of bytes used for an image pass
976 977 978 979 |
# File 'lib/chunky_png/color.rb', line 976 def pass_bytesize(color_mode, depth, width, height) return 0 if width == 0 || height == 0 (scanline_bytesize(color_mode, depth, width) + 1) * height end |
#pixel_bitsize(color_mode, depth = 8) ⇒ Integer
Returns the size in bits of a pixel when it is stored using a given color mode.
955 956 957 |
# File 'lib/chunky_png/color.rb', line 955 def pixel_bitsize(color_mode, depth = 8) samples_per_pixel(color_mode) * depth end |
#pixel_bytesize(color_mode, depth = 8) ⇒ Integer
Returns the size in bytes of a pixel when it is stored using a given color mode.
943 944 945 946 |
# File 'lib/chunky_png/color.rb', line 943 def pixel_bytesize(color_mode, depth = 8) return 1 if depth < 8 (pixel_bitsize(color_mode, depth) + 7) >> 3 end |
#r(value) ⇒ Integer
Returns the red-component from the color value.
272 273 274 |
# File 'lib/chunky_png/color.rb', line 272 def r(value) (value & 0xff000000) >> 24 end |
#rgb(r, g, b) ⇒ Integer
Creates a new color using an r, g, b triple.
109 110 111 |
# File 'lib/chunky_png/color.rb', line 109 def rgb(r, g, b) r << 24 | g << 16 | b << 8 | 0xff end |
#rgba(r, g, b, a) ⇒ Integer
Creates a new color using an r, g, b triple and an alpha value.
100 101 102 |
# File 'lib/chunky_png/color.rb', line 100 def rgba(r, g, b, a) r << 24 | g << 16 | b << 8 | a end |
#samples_per_pixel(color_mode) ⇒ Integer
Returns the number of sample values per pixel.
926 927 928 929 930 931 932 933 934 935 |
# File 'lib/chunky_png/color.rb', line 926 def samples_per_pixel(color_mode) case color_mode when ChunkyPNG::COLOR_INDEXED; 1 when ChunkyPNG::COLOR_TRUECOLOR; 3 when ChunkyPNG::COLOR_TRUECOLOR_ALPHA; 4 when ChunkyPNG::COLOR_GRAYSCALE; 1 when ChunkyPNG::COLOR_GRAYSCALE_ALPHA; 2 else raise ChunkyPNG::NotSupported, "Don't know the number of samples for this colormode: #{color_mode}!" end end |
#scanline_bytesize(color_mode, depth, width) ⇒ Integer
Returns the number of bytes used per scanline.
965 966 967 |
# File 'lib/chunky_png/color.rb', line 965 def scanline_bytesize(color_mode, depth, width) ((pixel_bitsize(color_mode, depth) * width) + 7) >> 3 end |
#to_grayscale(color) ⇒ Integer
Converts a color to a fiting grayscale value. It will conserve the alpha channel.
This method will return a full color value, with the R, G, and B value set to the grayscale teint calcuated from the input color’s R, G and B values.
450 451 452 |
# File 'lib/chunky_png/color.rb', line 450 def to_grayscale(color) grayscale_alpha(grayscale_teint(color), a(color)) end |
#to_grayscale_alpha_bytes(color) ⇒ Array<Integer>
Returns an array with the grayscale teint and alpha channel values for this color.
This method expects the color to be grayscale, i.e. r, g, and b value to be equal and uses only the B channel. If you need to convert a color to grayscale first, see #to_grayscale.
695 696 697 |
# File 'lib/chunky_png/color.rb', line 695 def to_grayscale_alpha_bytes(color) [b(color), a(color)] # assumption r == g == b end |
#to_grayscale_bytes(color) ⇒ Array<Integer>
Returns an array with the grayscale teint value for this color.
This method expects the r, g, and b value to be equal, and the alpha channel will be discarded.
681 682 683 |
# File 'lib/chunky_png/color.rb', line 681 def to_grayscale_bytes(color) [b(color)] # assumption r == g == b end |
#to_hex(color, include_alpha = true) ⇒ String
Returns a string representing this color using hex notation (i.e. #rrggbbaa).
568 569 570 |
# File 'lib/chunky_png/color.rb', line 568 def to_hex(color, include_alpha = true) include_alpha ? ('#%08x' % color) : ('#%06x' % [color >> 8]) end |
#to_hsl(color, include_alpha = false) ⇒ Array<Fixnum>[0], ...
Returns an array with the separate HSL components of a color.
Because ChunkyPNG internally handles colors as Integers for performance reasons, some rounding occurs when importing or exporting HSL colors whose coordinates are float-based. Because of this rounding, #to_hsl and #from_hsl may not be perfect inverses.
This implementation follows the modern convention of 0 degrees hue indicating red.
619 620 621 622 623 624 625 626 |
# File 'lib/chunky_png/color.rb', line 619 def to_hsl(color, include_alpha = false) hue, chroma, max, min = hue_and_chroma(color) lightness = 0.5 * (max + min) saturation = chroma.zero? ? 0.0 : chroma.fdiv(1 - (2 * lightness - 1).abs) include_alpha ? [hue, saturation, lightness, a(color)] : [hue, saturation, lightness] end |
#to_hsv(color, include_alpha = false) ⇒ Array[0], ... Also known as: to_hsb
Returns an array with the separate HSV components of a color.
Because ChunkyPNG internally handles colors as Integers for performance reasons, some rounding occurs when importing or exporting HSV colors whose coordinates are float-based. Because of this rounding, #to_hsv and #from_hsv may not be perfect inverses.
This implementation follows the modern convention of 0 degrees hue indicating red.
591 592 593 594 595 596 597 598 |
# File 'lib/chunky_png/color.rb', line 591 def to_hsv(color, include_alpha = false) hue, chroma, max, min = hue_and_chroma(color) value = max saturation = chroma.zero? ? 0.0 : chroma.fdiv(value) include_alpha ? [hue, saturation, value, a(color)] : [hue, saturation, value] end |
#to_truecolor_alpha_bytes(color) ⇒ Array<Integer>
Returns an array with the separate RGBA values for this color.
661 662 663 |
# File 'lib/chunky_png/color.rb', line 661 def to_truecolor_alpha_bytes(color) [r(color), g(color), b(color), a(color)] end |
#to_truecolor_bytes(color) ⇒ Array<Integer>
Returns an array with the separate RGB values for this color. The alpha channel will be discarded.
670 671 672 |
# File 'lib/chunky_png/color.rb', line 670 def to_truecolor_bytes(color) [r(color), g(color), b(color)] end |