Module: Btape::Palette

Defined in:
lib/btape/palette.rb

Overview

The 256 colours a GIF frame is written in, and the mapping from a pixel to one of them.

Fixed spreads its colours evenly across the whole RGB cube regardless of what is being encoded, which costs nothing to build but wastes most of the palette on colours the image does not contain. Adaptive chooses the colours from the image itself, which is what keeps text edges and gradients from banding.

Defined Under Namespace

Classes: Adaptive, Fixed, MedianCut

Constant Summary collapse

SIZE =
256
LEVELS =

Colours are bucketed to five bits per channel before anything looks at them. It collapses a screenshot's million pixels into a few thousand distinct entries, and the error it introduces is below what the 256 colours of a GIF can express anyway.

32
CELLS =
LEVELS**3

Class Method Summary collapse

Class Method Details

.build(quantizer, images) ⇒ Object



25
26
27
# File 'lib/btape/palette.rb', line 25

def build(quantizer, images)
  quantizer.to_sym == :adaptive ? Adaptive.from(images) : Fixed.new
end

.cell(pixel) ⇒ Object



29
30
31
32
33
# File 'lib/btape/palette.rb', line 29

def cell(pixel)
  ((ChunkyPNG::Color.r(pixel) >> 3) << 10) |
    ((ChunkyPNG::Color.g(pixel) >> 3) << 5) |
    (ChunkyPNG::Color.b(pixel) >> 3)
end

.colour_table(colours) ⇒ Object

Pads a list of colours out to a full global colour table.



40
41
42
# File 'lib/btape/palette.rb', line 40

def colour_table(colours)
  colours.map { |colour| colour.pack('C3') }.join.b.ljust(SIZE * 3, "\x00".b)
end

.rgb(cell) ⇒ Object



35
36
37
# File 'lib/btape/palette.rb', line 35

def rgb(cell)
  [((cell >> 10) & 31) * 255 / 31, ((cell >> 5) & 31) * 255 / 31, (cell & 31) * 255 / 31]
end