Class: GD2::Palette

Inherits:
Object
  • Object
show all
Defined in:
lib/gd2/palette.rb

Overview

Description

Palette objects are associated with an Image and hold the selection of pixel colors available to the Image. This is primarily a concern for Image::IndexedColor images, but their use with Image::TrueColor images is supported for consistency.

Obtaining

Obtain a Palette object from the associated Image:

palette = image.palette

Direct Known Subclasses

IndexedColor, TrueColor

Defined Under Namespace

Classes: ColorNotFoundError, IndexedColor, PaletteFullError, TrueColor

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(image) ⇒ Palette

:nodoc:


26
27
28
# File 'lib/gd2/palette.rb', line 26

def initialize(image)   #:nodoc:
  @image = image
end

Instance Attribute Details

#imageObject (readonly)

The Image associated with this Palette


24
25
26
# File 'lib/gd2/palette.rb', line 24

def image
  @image
end

Instance Method Details

#<<(color) ⇒ Object

Ensure the given color is present in this palette, allocating it if necessary. Returns the palette so calls may be stacked.


140
141
142
143
# File 'lib/gd2/palette.rb', line 140

def <<(color)
  exact(color) or allocate(color)
  self
end

#[](index) ⇒ Object

Return the color allocated to the specified index, or nil if the entry is unallocated.

Raises:

  • (RangeError)

56
57
58
59
60
61
# File 'lib/gd2/palette.rb', line 56

def [](index)
  index = size + index if index < 0
  raise RangeError unless (0...size).include? index
  return nil unless allocated?(index)
  get_color(index)
end

#[]=(index, color) ⇒ Object

Assign (allocate) the given color to the palette entry identified by index. If the entry was previously allocated to a different color, every pixel in the image having the given color index will effectively be changed to the new color. This method cannot be used with Image::TrueColor palettes.

Raises:

  • (RangeError)

68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/gd2/palette.rb', line 68

def []=(index, color)
  raise RangeError unless (0...MAX_COLORS).include? index
  if color.nil?
    deallocate(self[index] ||
      Color.new_from_palette(0, 0, 0, 0, index, self))
  else
    ptr = @image.image_ptr
    ptr[:red][index] = color.red
    ptr[:green][index] = color.green
    ptr[:blue][index] = color.blue
    ptr[:alpha][index] = color.alpha
    ptr[:open][index] = 0
  end
end

#allocate(color) ⇒ Object

Assign the given color to an unoccupied entry in this palette and return it. Does not check whether the color is already allocated, and raises an error for Image::IndexedColor palettes if the palette is full.

Raises:

  • (TypeError)

130
131
132
133
134
135
136
# File 'lib/gd2/palette.rb', line 130

def allocate(color)
  raise TypeError unless color.kind_of? Color
  c = ::GD2::GD2FFI.send(:gdImageColorAllocateAlpha, @image.image_ptr,
    color.red.to_i, color.green.to_i, color.blue.to_i, color.alpha.to_i)
  c == -1 ? raise(Palette::PaletteFullError, 'Palette is full') :
    get_color(c)
end

#availableObject

Return the number of palette entries available to be allocated for new colors.


50
51
52
# File 'lib/gd2/palette.rb', line 50

def available
  size - used
end

#closest(color) ⇒ Object

Return the color in this palette that is closest to the given color according to Euclidian distance.

Raises:

  • (TypeError)

111
112
113
114
115
116
# File 'lib/gd2/palette.rb', line 111

def closest(color)
  raise TypeError unless color.kind_of? Color
  c = ::GD2::GD2FFI.send(:gdImageColorClosestAlpha, @image.image_ptr,
    color.red.to_i, color.green.to_i, color.blue.to_i, color.alpha.to_i)
  c == -1 ? nil : get_color(c)
end

#closest_hwb(color) ⇒ Object

Return the color in this palette that is closest to the given color according to hue, whiteness, and blackness.

Raises:

  • (TypeError)

120
121
122
123
124
125
# File 'lib/gd2/palette.rb', line 120

def closest_hwb(color)
  raise TypeError unless color.kind_of? Color
  c = ::GD2::GD2FFI.send(:gdImageColorClosestHWB, @image.image_ptr,
    color.red.to_i, color.green.to_i, color.blue.to_i)
  c == -1 ? nil : get_color(c)
end

#deallocate(color) ⇒ Object

Remove the given color from this palette.


146
147
148
149
150
151
# File 'lib/gd2/palette.rb', line 146

def deallocate(color)
  color = exact(color) unless color.index
  return nil if color.nil? || color.index.nil?
  ::GD2::GD2FFI.send(:gdImageColorDeallocate, @image.image_ptr, color.index.to_i)
  nil
end

#deallocate_unusedObject

Remove all colors from this palette that are not currently in use by the associated Image. This is an expensive operation. Returns the number of palette entries deallocated.


156
157
158
# File 'lib/gd2/palette.rb', line 156

def deallocate_unused
  # implemented by subclass
end

#exact(color) ⇒ Object

Locate the given color in this palette and return it. Returns nil if the color is not presently in the palette.

Raises:

  • (TypeError)

95
96
97
98
99
100
# File 'lib/gd2/palette.rb', line 95

def exact(color)
  raise TypeError unless color.kind_of? Color
  c = ::GD2::GD2FFI.send(:gdImageColorExactAlpha, @image.image_ptr,
    color.red.to_i, color.green.to_i, color.blue.to_i, color.alpha.to_i)
  c == -1 ? nil : get_color(c)
end

#exact!(color) ⇒ Object

Like Palette#exact except an error is raised if the color is not presently in the palette.


104
105
106
107
# File 'lib/gd2/palette.rb', line 104

def exact!(color)
  exact(color) or raise Palette::ColorNotFoundError,
    "Color #{color} is not in the palette"
end

#resolve(color) ⇒ Object

Locate the given color in this palette and return it if found; otherwise try to allocate the color, or if the palette is full, return a color from the palette that is closest to it.

Raises:

  • (TypeError)

86
87
88
89
90
91
# File 'lib/gd2/palette.rb', line 86

def resolve(color)
  raise TypeError unless color.kind_of? Color
  c = ::GD2::GD2FFI.send(:gdImageColorResolveAlpha, @image.image_ptr,
    color.red.to_i, color.green.to_i, color.blue.to_i, color.alpha.to_i)
  c == -1 ? nil : get_color(c)
end

#sizeObject Also known as: length

Return the maximum number of colors this palette can hold.


31
32
33
# File 'lib/gd2/palette.rb', line 31

def size
  MAX_COLORS
end

#usedObject

Return the number of colors presently allocated in this palette.


42
43
44
45
46
# File 'lib/gd2/palette.rb', line 42

def used
  (0...size).inject(0) do |sum, i|
    sum + (allocated?(i) ? 1 : 0)
  end
end