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:



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

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

Instance Attribute Details

#imageObject (readonly)

The Image associated with this Palette



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

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.



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

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)


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

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)


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

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)


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

def allocate(color)
  raise TypeError unless color.kind_of? Color
  c = 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.



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

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)


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

def closest(color)
  raise TypeError unless color.kind_of? Color
  c = 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)


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

def closest_hwb(color)
  raise TypeError unless color.kind_of? Color
  c = 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.



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

def deallocate(color)
  color = exact(color) unless color.index
  return nil if color.nil? || color.index.nil?
  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.



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

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)


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

def exact(color)
  raise TypeError unless color.kind_of? Color
  c = 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.



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

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)


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

def resolve(color)
  raise TypeError unless color.kind_of? Color
  c = 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.



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

def size
  MAX_COLORS
end

#usedObject

Return the number of colors presently allocated in this palette.



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

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