class ChunkyPNG::Palette
A palette describes the set of colors that is being used for an image.
A PNG image can contain an explicit palette which defines the colors of that image, but can also use an implicit palette, e.g. all truecolor colors or all grayscale colors.
This palette supports decoding colors from a palette if an explicit palette is provided in a PNG datastream, and it supports encoding colors to an explicit palette (stores as PLTE & tRNS chunks in a PNG file).
@see ChunkyPNG::Color
Public Class Methods
Source
# File lib/chunky_png/palette.rb 63 def self.from_canvas(canvas) 64 # Although we don't need to call .uniq.sort before initializing, because 65 # Palette subclasses SortedSet, we get significantly better performance 66 # by doing so. 67 new(canvas.pixels.uniq.sort) 68 end
Builds a palette instance from a given canvas. @param canvas [ChunkyPNG::Canvas] The canvas to create a palette for. @return [ChunkyPNG::Palette] The palette instance.
Source
# File lib/chunky_png/palette.rb 41 def self.from_chunks(palette_chunk, transparency_chunk = nil) 42 return nil if palette_chunk.nil? 43 44 decoding_map = [] 45 index = 0 46 47 palatte_bytes = palette_chunk.content.unpack("C*") 48 alpha_channel = transparency_chunk ? transparency_chunk.content.unpack("C*") : [] 49 50 index = 0 51 palatte_bytes.each_slice(3) do |bytes| 52 bytes << alpha_channel.fetch(index, ChunkyPNG::Color::MAX) 53 decoding_map << ChunkyPNG::Color.rgba(*bytes) 54 index += 1 55 end 56 57 new(decoding_map, decoding_map) 58 end
Builds a palette instance from a PLTE chunk and optionally a tRNS chunk from a PNG datastream.
This method will cerate a palette that is suitable for decoding an image.
@param palette_chunk [ChunkyPNG::Chunk::Palette] The palette chunk to
load from
@param transparency_chunk [ChunkyPNG::Chunk::Transparency, nil] The
optional transparency chunk.
@return [ChunkyPNG::Palette] The loaded palette instance. @see ChunkyPNG::Palette#can_decode?
Source
# File lib/chunky_png/palette.rb 74 def self.from_pixels(pixels) 75 new(pixels) 76 end
Builds a palette instance from a given set of pixels. @param pixels [Enumerable<Integer>] An enumeration of pixels to create a
palette for
@return [ChunkyPNG::Palette] The palette instance.
Source
# File lib/chunky_png/palette.rb 23 def initialize(enum, decoding_map = nil) 24 super(enum.sort.freeze) 25 @decoding_map = decoding_map if decoding_map 26 @encoding_map = {} 27 freeze 28 end
Builds a new palette given a set (Enumerable instance) of colors.
@param enum [Enumerable<Integer>] The set of colors to include in this
palette.This Enumerable can contain duplicates.
@param decoding_map [Array] An array of colors in the exact order at
which they appeared in the palette chunk, so that this array can be used for decoding.
Public Instance Methods
Source
# File lib/chunky_png/palette.rb 148 def [](index) 149 @decoding_map[index] 150 end
Returns a color, given the position in the original palette chunk. @param index [Integer] The 0-based position of the color in the palette. @return [ChunkyPNG::Color] The color that is stored in the palette under
the given index
Source
# File lib/chunky_png/palette.rb 195 def best_color_settings 196 if black_and_white? 197 [ChunkyPNG::COLOR_GRAYSCALE, 1] 198 elsif grayscale? 199 if opaque? 200 [ChunkyPNG::COLOR_GRAYSCALE, 8] 201 else 202 [ChunkyPNG::COLOR_GRAYSCALE_ALPHA, 8] 203 end 204 elsif indexable? 205 [ChunkyPNG::COLOR_INDEXED, determine_bit_depth] 206 elsif opaque? 207 [ChunkyPNG::COLOR_TRUECOLOR, 8] 208 else 209 [ChunkyPNG::COLOR_TRUECOLOR_ALPHA, 8] 210 end 211 end
Determines the most suitable colormode for this palette. @return [Integer] The colormode which would create the smallest possible
file for images that use this exact palette.
Source
# File lib/chunky_png/palette.rb 104 def black_and_white? 105 entries == [ChunkyPNG::Color::BLACK, ChunkyPNG::Color::WHITE] 106 end
Check whether this palette only contains bacl and white. @return [true, false] True if all colors in this palette are grayscale
teints.
Source
# File lib/chunky_png/palette.rb 126 def can_decode? 127 !@decoding_map.nil? 128 end
Checks whether this palette is suitable for decoding an image from a datastream.
This requires that the positions of the colors in the original palette chunk is known, which is stored as an array in the +@decoding_map+ instance variable.
@return [true, false] True if a decoding map was built when this palette
was loaded.
Source
# File lib/chunky_png/palette.rb 139 def can_encode? 140 !@encoding_map.empty? 141 end
Checks whether this palette is suitable for encoding an image from to datastream.
This requires that the position of the color in the future palette chunk is known, which is stored as a hash in the +@encoding_map+ instance variable.
@return [true, false] True if a encoding map was built when this palette
was loaded.
Source
# File lib/chunky_png/palette.rb 216 def determine_bit_depth 217 case size 218 when 1..2 then 1 219 when 3..4 then 2 220 when 5..16 then 4 221 when 17..256 then 8 222 end 223 end
Determines the minimal bit depth required for an indexed image @return [Integer] Number of bits per pixel, i.e. 1, 2, 4 or 8, or nil if
this image cannot be saved as an indexed image.
Source
# File lib/chunky_png/palette.rb 96 def grayscale? 97 all? { |color| Color.grayscale?(color) } 98 end
Check whether this palette only contains grayscale colors. @return [true, false] True if all colors in this palette are grayscale
teints.
Source
# File lib/chunky_png/palette.rb 156 def index(color) 157 color.nil? ? 0 : @encoding_map[color] 158 end
Returns the position of a color in the palette @param color [ChunkyPNG::Color] The color for which to look up the index. @return [Integer] The 0-based position of the color in the palette. @see ChunkyPNG::Palette#can_encode?
Source
# File lib/chunky_png/palette.rb 81 def indexable? 82 size <= 256 83 end
Checks whether the size of this palette is suitable for indexed storage. @return [true, false] True if the number of colors in this palette is at
most 256.
Source
# File lib/chunky_png/palette.rb 88 def opaque? 89 all? { |color| Color.opaque?(color) } 90 end
Check whether this palette only contains opaque colors. @return [true, false] True if all colors in this palette are opaque. @see ChunkyPNG::Color#opaque?
Source
# File lib/chunky_png/palette.rb 113 def opaque_palette 114 self.class.new(map { |c| ChunkyPNG::Color.opaque!(c) }) 115 end
Returns a palette with all the opaque variants of the colors in this palette. @return [ChunkyPNG::Palette] A new Palette
instance with only opaque
colors.
Source
# File lib/chunky_png/palette.rb 180 def to_plte_chunk 181 @encoding_map.clear 182 colors = [] 183 184 each_with_index do |color, index| 185 @encoding_map[color] = index 186 colors += ChunkyPNG::Color.to_truecolor_bytes(color) 187 end 188 189 ChunkyPNG::Chunk::Palette.new("PLTE", colors.pack("C*")) 190 end
Creates a PLTE chunk that corresponds with this palette to store the r, g, and b channels of all colors.
@note A PLTE chunk should only be included if the image is encoded using
index colors. After this chunk has been built, the palette becomes suitable for encoding an image.
@return [ChunkyPNG::Chunk::Palette] The PLTE chunk. @see ChunkyPNG::Palette#can_encode?
Source
# File lib/chunky_png/palette.rb 167 def to_trns_chunk 168 ChunkyPNG::Chunk::Transparency.new("tRNS", map { |c| ChunkyPNG::Color.a(c) }.pack("C*")) 169 end
Creates a tRNS chunk that corresponds with this palette to store the alpha channel of all colors.
Note that this chunk can be left out of every color in the palette is opaque, and the image is encoded using indexed colors.
@return [ChunkyPNG::Chunk::Transparency] The tRNS chunk.