A convenience class that wraps the logic for extracting the parts of a PNG image that we need to embed them in a PDF
Process a new PNG image
data
A binary string of PNG data
# File lib/prawn/images/png.rb, line 29 def initialize(data) data = StringIO.new(data.dup) data.read(8) # Skip the default header @palette = "" @img_data = "" @transparency = {} loop do chunk_size = data.read(4).unpack("N")[0] section = data.read(4) case section when 'IHDR' # we can grab other interesting values from here (like width, # height, etc) values = data.read(chunk_size).unpack("NNCCCCC") @width = values[0] @height = values[1] @bits = values[2] @color_type = values[3] @compression_method = values[4] @filter_method = values[5] @interlace_method = values[6] when 'PLTE' @palette << data.read(chunk_size) when 'IDAT' @img_data << data.read(chunk_size) when 'tRNS' # This chunk can only occur once and it must occur after the # PLTE chunk and before the IDAT chunk @transparency = {} case @color_type when 3 # Indexed colour, RGB. Each byte in this chunk is an alpha for # the palette index in the PLTE ("palette") chunk up until the # last non-opaque entry. Set up an array, stretching over all # palette entries which will be 0 (opaque) or 1 (transparent). @transparency[:indexed] = data.read(chunk_size).unpack("C*") short = 255 - @transparency[:indexed].size @transparency[:indexed] += ([255] * short) if short > 0 when 0 # Greyscale. Corresponding to entries in the PLTE chunk. # Grey is two bytes, range 0 .. (2 ^ bit-depth) - 1 grayval = data.read(chunk_size).unpack("n").first @transparency[:grayscale] = grayval when 2 # True colour with proper alpha channel. @transparency[:rgb] = data.read(chunk_size).unpack("nnn") end when 'IEND' # we've got everything we need, exit the loop break else # unknown (or un-important) section, skip over it data.seek(data.pos + chunk_size) end data.read(4) # Skip the CRC end end
number of color components to each pixel
# File lib/prawn/images/png.rb, line 94 def colors case self.color_type when 0, 3, 4 return 1 when 2, 6 return 3 end end
number of bits used per pixel
# File lib/prawn/images/png.rb, line 105 def pixel_bitlength if alpha_channel? self.bits * (self.colors + 1) else self.bits * self.colors end end
split the alpha channel data from the raw image data in images where it’s required.
# File lib/prawn/images/png.rb, line 116 def split_alpha_channel! unfilter_image_data if alpha_channel? end