module ChunkyPNG::Color
def a(value)
-
(Integer)
- A value between 0 and MAX.
Parameters:
-
value
(Integer
) -- The color value.
def a(value) value & 0x000000ff end
def alpha_decomposable?(color, mask, bg, tolerance = 1)
- See: #decompose_alpha -
Returns:
-
(Boolean)
- True if the alpha component can be decomposed successfully.
Parameters:
-
tolerance
(Integer
) -- The decomposition tolerance level, a value between 0 and 255. -
bg
(Integer
) -- The background color on which the color was composed. -
mask
(Integer
) -- The opaque variant of the color that was being composed -
color
(Integer
) -- The color that was the result of compositing.
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 return components.max <= 255 && components.min >= 0 && (sum + tolerance * 3) >= max end
def b(value)
-
(Integer)
- A value between 0 and MAX.
Parameters:
-
value
(Integer
) -- The color value.
def b(value) (value & 0x0000ff00) >> 8 end
def blend(fg, bg)
-
(Integer)
- The blended color.
Parameters:
-
bg
(Integer
) -- The foreground color. -
fg
(Integer
) -- The foreground color.
def blend(fg, bg) (fg + bg) >> 1 end
def compose_precise(fg, bg)
- See: ChunkyPNG::Color#compose_quick -
Returns:
-
(Integer)
- The composited color.
Parameters:
-
bg
(Integer
) -- The foreground color. -
fg
(Integer
) -- The foreground color.
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
def compose_quick(fg, bg)
- See: ChunkyPNG::Color#compose_precise -
Returns:
-
(Integer)
- The composited color.
Parameters:
-
bg
(Integer
) -- The foreground color. -
fg
(Integer
) -- The foreground color.
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
def decompose_alpha(color, mask, bg)
- See: #alpha_decomposable? -
Returns:
-
(Integer)
- The best fitting alpha channel, a value between 0 and 255.
Parameters:
-
bg
(Integer
) -- The background color on which the color was composed. -
mask
(Integer
) -- The opaque variant of the color that was being composed -
color
(Integer
) -- The color that was the result of compositing.
def decompose_alpha(color, mask, bg) components = decompose_alpha_components(color, mask, bg) (components.inject(0) { |a,b| a + b } / 3.0).round end
def decompose_alpha_component(channel, color, mask, bg)
-
(Integer)
- The decomposed alpha value for the channel.
Parameters:
-
bg
(Integer
) -- The background color on which the color was composed. -
mask
(Integer
) -- The opaque variant of the color that was being composed -
color
(Integer
) -- The color that was the result of compositing. -
channel
(:r, :g, :b
) -- The channel to decompose the alpha channel from.
def decompose_alpha_component(channel, color, mask, bg) ((send(channel, bg) - send(channel, color)).to_f / (send(channel, bg) - send(channel, mask)).to_f * MAX).round end
def decompose_alpha_components(color, mask, bg)
-
(Array
- The decomposed alpha values for the r, g and b channels.)
Parameters:
-
bg
(Integer
) -- The background color on which the color was composed. -
mask
(Integer
) -- The opaque variant of the color that was being composed -
color
(Integer
) -- The color that was the result of compositing.
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
def decompose_color(color, mask, bg, tolerance = 1)
-
(Integer)
- The decomposed color,a variant of the masked color with the
Parameters:
-
tolerance
(Integer
) -- The decomposition tolerance level, a value between 0 and 255. -
bg
(Integer
) -- The background color on which the color was composed. -
mask
(Integer
) -- The opaque variant of the color that was being composed -
color
(Integer
) -- The color that was the result of compositing.
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
def fade(color, factor)
-
(Integer)
- The faded color.
Parameters:
-
factor
(Integer
) -- Fade factor as an integer between 0 and 255. -
color
(Integer
) -- The color to adjust.
def fade(color, factor) new_alpha = int8_mult(a(color), factor) (color & 0xffffff00) | new_alpha end
def from_hex(hex_value, opacity = nil)
-
(ArgumentError)
- if the value given is not a hex color notation.
Returns:
-
(Integer)
- The color value.
Parameters:
-
opacity
(Integer
) -- The opacity value for the color. Overrides any -
str
(String
) -- The color in hex notation. @return [Integer] The
def from_hex(hex_value, opacity = nil) if HEX_COLOR_REGEXP =~ hex_value base_color = $1.hex << 8 opacity ||= $2 ? $2.hex : 0xff base_color | opacity else raise ArgumentError, "Not a valid hex color notation: #{hex_value.inspect}!" end end
def from_rgb_stream(stream, pos = 0)
-
(Integer)
- The newly constructed color value.
Parameters:
-
pos
(Integer
) -- The position in the string to load the triple from. -
stream
(String
) -- The string to load the color from. It should be
def from_rgb_stream(stream, pos = 0) rgb(*stream.unpack("@#{pos}C3")) end
def from_rgba_stream(stream, pos = 0)
-
(Integer)
- The newly constructed color value.
Parameters:
-
pos
(Integer
) -- The position in the string to load the triple from. -
stream
(String
) -- The string to load the color from. It should be
def from_rgba_stream(stream, pos = 0) rgba(*stream.unpack("@#{pos}C4")) end
def fully_transparent?(value)
-
(true, false)
- True if the alpha channel equals 0.
Parameters:
-
value
(Integer
) -- The color to test.
def fully_transparent?(value) a(value) == 0x00000000 end
def g(value)
-
(Integer)
- A value between 0 and MAX.
Parameters:
-
value
(Integer
) -- The color value.
def g(value) (value & 0x00ff0000) >> 16 end
def grayscale(teint)
-
(Integer)
- The newly constructed color value.
Parameters:
-
teint
(Integer
) -- The grayscale teint (0-255), will be used as r, g, and b value.
def grayscale(teint) teint << 24 | teint << 16 | teint << 8 | 0xff end
def grayscale?(value)
-
(true, false)
- True if the r, g and b component are equal.
Parameters:
-
value
(Integer
) -- The color to test.
def grayscale?(value) r(value) == b(value) && b(value) == g(value) end
def grayscale_alpha(teint, a)
-
(Integer)
- The newly constructed color value.
Parameters:
-
a
(Integer
) -- The opacity (0-255) -
teint
(Integer
) -- The grayscale teint (0-255), will be used as r, g, and b value.
def grayscale_alpha(teint, a) teint << 24 | teint << 16 | teint << 8 | a end
def html_color(color_name, opacity = nil)
-
(ChunkyPNG::Exception)
- If the color name was not recognized.
Returns:
-
(Integer)
- The color value.
Parameters:
-
opacity
(Integer
) -- The opacity value for the color between 0 and 255. Overrides -
color_name
(Symbol, String
) -- The color name. It may include an opacity specifier
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
def int8_mult(a, b)
-
(Integer)
- The result of the multiplication.
Parameters:
-
b
(Integer
) -- The second fraction. -
a
(Integer
) -- The first fraction.
def int8_mult(a, b) t = a * b + 0x80 ((t >> 8) + t) >> 8 end
def opaque!(value)
-
(Integer)
- The opaque color
Parameters:
-
value
(Integer
) -- The color to transform.
def opaque!(value) value | 0x000000ff end
def opaque?(value)
-
(true, false)
- True if the alpha channel equals MAX.
Parameters:
-
value
(Integer
) -- The color to test.
def opaque?(value) a(value) == 0x000000ff end
def parse(source)
-
(Integer)
- The color value, with the opacity applied if one was given.
Parameters:
-
The
(Integer, String
) -- color value.
def parse(source) return source if source.kind_of?(Integer) case source.to_s when /^\d+$/; source.to_s.to_i when ChunkyPNG::Color::HEX_COLOR_REGEXP; ChunkyPNG::Color.from_hex(source.to_s) when ChunkyPNG::Color::HTML_COLOR_REGEXP; ChunkyPNG::Color.html_color(source.to_s) else raise ArgumentError, "Don't know how to create a color from #{source.inspect}!" end end
def pass_bytesize(color_mode, depth, width, height)
-
(Integer)
- The number of bytes used per scanline in a datastream.
Parameters:
-
width
(Integer
) -- The height of the image pass. -
width
(Integer
) -- The width of the image pass. -
depth
(Integer
) -- The color depth of the pixels. -
color_mode
(Integer
) -- The color mode in which the pixels are stored.
def pass_bytesize(color_mode, depth, width, height) return 0 if width == 0 || height == 0 (scanline_bytesize(color_mode, depth, width) + 1) * height end
def pixel_bitsize(color_mode, depth = 8)
-
(Integer)
- The number of bytes used per pixel in a datastream.
Parameters:
-
depth
(Integer
) -- The color depth of the pixels. -
color_mode
(Integer
) -- The color mode in which the pixels are stored.
def pixel_bitsize(color_mode, depth = 8) samples_per_pixel(color_mode) * depth end
def pixel_bytesize(color_mode, depth = 8)
-
(Integer)
- The number of bytes used per pixel in a datastream.
Parameters:
-
color_mode
(Integer
) -- The color mode in which the pixels are stored.
def pixel_bytesize(color_mode, depth = 8) return 1 if depth < 8 (pixel_bitsize(color_mode, depth) + 7) >> 3 end
def r(value)
-
(Integer)
- A value between 0 and MAX.
Parameters:
-
value
(Integer
) -- The color value.
def r(value) (value & 0xff000000) >> 24 end
def rgb(r, g, b)
-
(Integer)
- The newly constructed color value.
Parameters:
-
b
(Integer
) -- The b-component (0-255) -
g
(Integer
) -- The g-component (0-255) -
r
(Integer
) -- The r-component (0-255)
def rgb(r, g, b) r << 24 | g << 16 | b << 8 | 0xff end
def rgba(r, g, b, a)
-
(Integer)
- The newly constructed color value.
Parameters:
-
a
(Integer
) -- The opacity (0-255) -
b
(Integer
) -- The b-component (0-255) -
g
(Integer
) -- The g-component (0-255) -
r
(Integer
) -- The r-component (0-255)
def rgba(r, g, b, a) r << 24 | g << 16 | b << 8 | a end
def samples_per_pixel(color_mode)
-
(Integer)
- The number of sample values per pixel.
Parameters:
-
color_mode
(Integer
) -- The color mode being used.
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 numer of samples for this colormode: #{color_mode}!" end end
def scanline_bytesize(color_mode, depth, width)
-
(Integer)
- The number of bytes used per scanline in a datastream.
Parameters:
-
width
(Integer
) -- The number of pixels per scanline. -
depth
(Integer
) -- The color depth of the pixels. -
color_mode
(Integer
) -- The color mode in which the pixels are stored.
def scanline_bytesize(color_mode, depth, width) ((pixel_bitsize(color_mode, depth) * width) + 7) >> 3 end
def to_grayscale_alpha_bytes(color)
-
(Array
- An array with 2 Integer elements.)
Parameters:
-
color
(Integer
) -- The grayscale color to convert.
def to_grayscale_alpha_bytes(color) [b(color), a(color)] # assumption r == g == b end
def to_grayscale_bytes(color)
-
(Array
- An array with 1 Integer element.)
Parameters:
-
color
(Integer
) -- The grayscale color to convert.
def to_grayscale_bytes(color) [b(color)] # assumption r == g == b end
def to_hex(color, include_alpha = true)
-
(String)
- The color in hex notation, starting with a pound sign.
Parameters:
-
value
(Integer
) -- The color to convert.
def to_hex(color, include_alpha = true) include_alpha ? ('#%08x' % color) : ('#%06x' % [color >> 8]) end
def to_truecolor_alpha_bytes(color)
-
(Array
- An array with 4 Integer elements.)
Parameters:
-
color
(Integer
) -- The color to convert.
def to_truecolor_alpha_bytes(color) [r(color), g(color), b(color), a(color)] end
def to_truecolor_bytes(color)
-
(Array
- An array with 3 Integer elements.)
Parameters:
-
color
(Integer
) -- The color to convert.
def to_truecolor_bytes(color) [r(color), g(color), b(color)] end