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:



45
46
47
# File 'lib/gd2/palette.rb', line 45

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

Instance Attribute Details

#imageObject (readonly)

The Image associated with this Palette



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

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.



159
160
161
162
# File 'lib/gd2/palette.rb', line 159

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)


75
76
77
78
79
80
# File 'lib/gd2/palette.rb', line 75

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)


87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/gd2/palette.rb', line 87

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)


149
150
151
152
153
154
155
# File 'lib/gd2/palette.rb', line 149

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.



69
70
71
# File 'lib/gd2/palette.rb', line 69

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)


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

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)


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

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.



165
166
167
168
169
170
# File 'lib/gd2/palette.rb', line 165

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.



175
176
177
# File 'lib/gd2/palette.rb', line 175

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)


114
115
116
117
118
119
# File 'lib/gd2/palette.rb', line 114

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.



123
124
125
126
# File 'lib/gd2/palette.rb', line 123

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)


105
106
107
108
109
110
# File 'lib/gd2/palette.rb', line 105

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.



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

def size
  MAX_COLORS
end

#usedObject

Return the number of colors presently allocated in this palette.



61
62
63
64
65
# File 'lib/gd2/palette.rb', line 61

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