Class: GD2::Image

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/gd2/image.rb

Overview

Introduction

Image is the abstract base class for Image::IndexedColor and Image::TrueColor.

Creating and Importing

Image objects are created either as a blank array of pixels:

image = Image::IndexedColor.new(width, height)
image = Image::TrueColor.new(width, height)

or by loading image data from a file or a string containing one of the supported image formats:

image = Image.load(file)
image = Image.load(string)

or by importing image data from a file given by its pathname:

image = Image.import(filename)

Exporting

After manipulating an image, it can be exported to a string in one of the supported image formats:

image.jpeg(quality = nil)
image.png(level = nil)
image.gif
image.wbmp(fgcolor)
image.gd
image.gd2(fmt = FMT_COMPRESSED)

or to a file in a format determined by the filename extension:

image.export(filename, options = {})

Direct Known Subclasses

IndexedColor, TrueColor

Defined Under Namespace

Classes: IndexedColor, TrueColor, UnrecognizedImageTypeError

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#image_ptrObject (readonly)

:nodoc:



66
67
68
# File 'lib/gd2/image.rb', line 66

def image_ptr
  @image_ptr
end

#paletteObject (readonly)

The Palette object for this image



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

def palette
  @palette
end

Class Method Details

.create_image_ptr(sx, sy, alpha_blending = true) ⇒ Object

:nodoc:



224
225
226
227
228
# File 'lib/gd2/image.rb', line 224

def self.create_image_ptr(sx, sy, alpha_blending = true)  #:nodoc:
  ptr = FFIStruct::ImagePtr.new(GD2FFI.send(create_image_sym, sx.to_i, sy.to_i))
  GD2FFI.send(:gdImageAlphaBlending, ptr, alpha_blending ? 1 : 0)
  ptr
end

.import(filename, options = {}) ⇒ Object

Import an image from a file with the given filename. The :format option or the file extension is used to determine the image type (jpeg, png, gif, wbmp, gd, gd2, xbm, or xpm). The resulting image will be either of class Image::TrueColor or Image::IndexedColor.

If the file format is gd2, it is optionally possible to extract only a part of the image. Use options :x, :y, :width, and :height to specify the part of the image to import.

Raises:

  • (Errno::ENOENT)


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/gd2/image.rb', line 159

def self.import(filename, options = {})
  raise Errno::ENOENT.new(filename) unless File.exists?(filename)

  unless format = options.delete(:format)
    md = filename.match(/\.([^.]+)\z/)
    format = md ? md[1].downcase : nil
  end
  format = format.to_sym if format

  ptr = # TODO: implement xpm and xbm imports
  #if format == :xpm
    #raise ArgumentError, "Unexpected options #{options.inspect}" unless options.empty?
    #GD2FFI.send(:gdImageCreateFromXpm, filename)
  #elsif format == :xbm
    #GD2FFI.send(:gdImageCreateFromXbm, filename)
  if format == :gd2 && !options.empty?
    x, y, width, height =
      options.delete(:x) || 0, options.delete(:y) || 0,
      options.delete(:width)  || options.delete(:w),
      options.delete(:height) || options.delete(:h)
    raise ArgumentError, "Unexpected options #{options.inspect}" unless
      options.empty?
    raise ArgumentError, 'Missing required option :width' if width.nil?
    raise ArgumentError, 'Missing required option :height' if height.nil?
    # TODO:
    ptr = File.open(filename, 'rb') do |file|
      GD2FFI.send(:gdImageCreateFromGd2Part, file, x.to_i, y.to_i, width.to_i, height.to_i)
    end
  else
    raise ArgumentError, "Unexpected options #{options.inspect}" unless
      options.empty?
    create_sym = {
      :jpeg => :gdImageCreateFromJpegPtr,
      :jpg  => :gdImageCreateFromJpegPtr,
      :png  => :gdImageCreateFromPngPtr,
      :gif  => :gdImageCreateFromGifPtr,
      :wbmp => :gdImageCreateFromWBMPPtr,
      :gd   => :gdImageCreateFromGdPtr,
      :gd2  => :gdImageCreateFromGd2Ptr
    }[format]
    raise UnrecognizedImageTypeError,
      'Format (or file extension) is not recognized' unless create_sym

    file = File.read(filename)
    file = file.force_encoding("BINARY") if file.respond_to? :force_encoding
    file_ptr = FFI::MemoryPointer.new(file.size, 1, false)
    file_ptr.put_bytes(0, file)

    GD2FFI.send(create_sym, file.size, file_ptr)
  end
  raise LibraryError unless ptr

  ptr = FFIStruct::ImagePtr.new(ptr)

  image = (image_true_color?(ptr) ?
    TrueColor : IndexedColor).allocate.init_with_image(ptr)

  block_given? ? yield(image) : image
end

.load(src) ⇒ Object

Load an image from a file or a string. The image type is detected automatically (JPEG, PNG, GIF, WBMP, or GD2). The resulting image will be either of class Image::TrueColor or Image::IndexedColor.

Raises:



90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/gd2/image.rb', line 90

def self.load(src)
  src = src.force_encoding("BINARY") if src.respond_to? :force_encoding
  case src
  when File
    pos = src.pos
    magic = src.read(4)
    src.pos = pos
    data = src.read
    data = data.force_encoding("BINARY") if data.respond_to? :force_encoding
    args = [ data.length, data ]
  when String
    magic = src
    args = [ src.length, src ]
  else
    raise TypeError, 'Unexpected argument type'
  end

  create = {
    :jpeg => :gdImageCreateFromJpegPtr,
    :png  => :gdImageCreateFromPngPtr,
    :gif  => :gdImageCreateFromGifPtr,
    :wbmp => :gdImageCreateFromWBMPPtr,
    :gd2  => :gdImageCreateFromGd2Ptr
  }

  type = data_type(magic) or
    raise UnrecognizedImageTypeError, 'Image data format is not recognized'
  ptr = GD2FFI.send(create[type], *args)
  raise LibraryError unless ptr

  ptr = FFIStruct::ImagePtr.new(ptr)

  image = (image_true_color?(ptr) ?
    TrueColor : IndexedColor).allocate.init_with_image(ptr)

  block_given? ? yield(image) : image
end

.new(w, h) ⇒ Object Also known as: []

Create a new image of the specified dimensions. The default image class is Image::TrueColor; call this method on Image::IndexedColor instead if a palette image is desired.



76
77
78
79
80
81
# File 'lib/gd2/image.rb', line 76

def self.new(w, h)
  image = (self == Image) ?
    TrueColor.new(w, h) : allocate.init_with_size(w, h)

  block_given? ? yield(image) : image
end

Instance Method Details

#==(other) ⇒ Object

Compare this image with another image. Returns false if the images are not identical.



265
266
267
# File 'lib/gd2/image.rb', line 265

def ==(other)
  (compare(other) & CMP_IMAGE).zero?
end

#[](x, y) ⇒ Object

Return the color of the pixel at image location (x, y).



311
312
313
# File 'lib/gd2/image.rb', line 311

def [](x, y)
  pixel2color(get_pixel(x, y))
end

#[]=(x, y, color) ⇒ Object

Set the color of the pixel at image location (x, y).



316
317
318
# File 'lib/gd2/image.rb', line 316

def []=(x, y, color)
  set_pixel(x, y, color2pixel(color))
end

#alpha_blending=(bool) ⇒ Object

Set whether colors should be alpha blended with existing colors when pixels are modified. Alpha blending is not available for IndexedColor images.



365
366
367
# File 'lib/gd2/image.rb', line 365

def alpha_blending=(bool)
  GD2FFI.send(:gdImageAlphaBlending, image_ptr, bool ? 1 : 0)
end

#alpha_blending?Boolean

Return true if colors will be alpha blended into the image when pixels are modified. Returns false if colors will be copied verbatim into the image without alpha blending when pixels are modified.

Returns:

  • (Boolean)


358
359
360
# File 'lib/gd2/image.rb', line 358

def alpha_blending?
  not image_ptr[:alphaBlendingFlag].zero?
end

#aspectObject

Return the aspect ratio of this image, as a floating point ratio of the width to the height.



294
295
296
# File 'lib/gd2/image.rb', line 294

def aspect
  width.to_f / height
end

#clippingObject

Return the current clipping rectangle. Use Image#with_clipping to temporarily modify the clipping rectangle.



396
397
398
399
400
401
402
403
404
# File 'lib/gd2/image.rb', line 396

def clipping
  x1 = FFI::MemoryPointer.new(:pointer)
  y1 = FFI::MemoryPointer.new(:pointer)
  x2 = FFI::MemoryPointer.new(:pointer)
  y2 = FFI::MemoryPointer.new(:pointer)

  GD2FFI.send(:gdImageGetClip, image_ptr, x1, y1, x2, y2)
  [ x1.read_int, y1.read_int, x2.read_int, y2.read_int ]
end

#clips?(x, y) ⇒ Boolean

Return true if the current clipping rectangle excludes the given point.

Returns:

  • (Boolean)


423
424
425
# File 'lib/gd2/image.rb', line 423

def clips?(x, y)
  GD2FFI.send(:gdImageBoundsSafe, image_ptr, x.to_i, y.to_i).zero?
end

#color2pixel(color) ⇒ Object

Return a pixel value for the given color object.



339
340
341
# File 'lib/gd2/image.rb', line 339

def color2pixel(color)
  color.rgba
end

#compare(other) ⇒ Object

Compare this image with another image. Returns 0 if the images are identical, otherwise a bit field indicating the differences. See the GD2::CMP_* constants for individual bit flags.



259
260
261
# File 'lib/gd2/image.rb', line 259

def compare(other)
  GD2FFI.send(:gdImageCompare, image_ptr, other.image_ptr)
end

#copy_from(other, dst_x, dst_y, src_x, src_y, dst_w, dst_h, src_w = nil, src_h = nil) ⇒ Object

Copy a portion of another image to this image. If src_w and src_h are specified, the indicated portion of the source image will be resized (and resampled) to fit the indicated dimensions of the destination.

Raises:

  • (ArgumentError)


563
564
565
566
567
568
569
570
571
572
573
574
# File 'lib/gd2/image.rb', line 563

def copy_from(other, dst_x, dst_y, src_x, src_y,
    dst_w, dst_h, src_w = nil, src_h = nil)
  raise ArgumentError unless src_w.nil? == src_h.nil?
  if src_w
    GD2FFI.send(:gdImageCopyResampled, image_ptr, other.image_ptr,
      dst_x.to_i, dst_y.to_i, src_x.to_i, src_y.to_i, dst_w.to_i, dst_h.to_i, src_w.to_i, src_h.to_i)
  else
    GD2FFI.send(:gdImageCopy, image_ptr, other.image_ptr,
      dst_x.to_i, dst_y.to_i, src_x.to_i, src_y.to_i, dst_w.to_i, dst_h.to_i)
  end
  self
end

#copy_from_rotated(other, dst_x, dst_y, src_x, src_y, w, h, angle) ⇒ Object

Copy a portion of another image to this image, rotating the source portion first by the indicated angle (in radians). The dst_x and dst_y arguments indicate the center of the desired destination, and may be floating point.



580
581
582
583
584
# File 'lib/gd2/image.rb', line 580

def copy_from_rotated(other, dst_x, dst_y, src_x, src_y, w, h, angle)
  GD2FFI.send(:gdImageCopyRotated, image_ptr, other.image_ptr,
    dst_x.to_f, dst_y.to_f, src_x.to_i, src_y.to_i, w.to_i, h.to_i, angle.to_degrees.round.to_i)
  self
end

#crop(x, y, w, h) ⇒ Object

Like Image#crop! except a new image is returned.



619
620
621
# File 'lib/gd2/image.rb', line 619

def crop(x, y, w, h)
  clone.crop!(x, y, w, h)
end

#crop!(x, y, w, h) ⇒ Object

Crop this image to the specified dimensions, such that (x, y) becomes (0, 0).



612
613
614
615
616
# File 'lib/gd2/image.rb', line 612

def crop!(x, y, w, h)
  ptr = self.class.create_image_ptr(w, h, alpha_blending?)
  GD2FFI.send(:gdImageCopy, ptr, image_ptr, 0, 0, x.to_i, y.to_i, w.to_i, h.to_i)
  init_with_image(ptr)
end

#draw {|Canvas.new(self)| ... } ⇒ Object

Provide a drawing environment for a block. See GD2::Canvas.

Yields:



428
429
430
431
# File 'lib/gd2/image.rb', line 428

def draw  #:yields: canvas
  yield Canvas.new(self)
  self
end

#dupObject

Duplicate this image, copying all pixels to a new image. Contrast with Image#clone which produces a shallow copy and shares internal pixel data.



252
253
254
# File 'lib/gd2/image.rb', line 252

def dup
  self.class.superclass.load(gd2(FMT_RAW))
end

#eachObject

Iterate over each row of pixels in the image, returning an array of pixel values.



322
323
324
325
326
327
328
329
330
331
# File 'lib/gd2/image.rb', line 322

def each
  ptr = image_ptr
  (0...height).each do |y|
    row = (0...width).inject(Array.new(width)) do |row, x|
      row[x] = get_pixel(x, y)
      row
    end
    yield row
  end
end

#export(filename, options = {}) ⇒ Object

Export this image to a file with the given filename. The image format is determined by the :format option, or by the file extension (jpeg, png, gif, wbmp, gd, or gd2). Returns the size of the written image data. Additional options are as arguments for the Image#jpeg, Image#png, Image#wbmp, or Image#gd2 methods.

Raises:

  • (ArgumentError)


445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
# File 'lib/gd2/image.rb', line 445

def export(filename, options = {})
  unless format = options.delete(:format)
    md = filename.match(/\.([^.]+)\z/)
    format = md ? md[1].downcase : nil
  end
  format = format.to_sym if format

  size = FFI::MemoryPointer.new(:pointer)

  case format
  when :jpeg, :jpg
    write_sym = :gdImageJpegPtr
    args = [ size, options.delete(:quality) || -1 ]
  when :png
    write_sym = :gdImagePngPtrEx
    args = [ size, options.delete(:level) || -1 ]
  when :gif
    write_sym = :gdImageGifPtr
    args = [ size ]
  when :wbmp
    write_sym = :gdImageWBMPPtr
    fgcolor = options.delete(:fgcolor)
    raise ArgumentError, 'Missing required option :fgcolor' if fgcolor.nil?
    args = [size, color2pixel(fgcolor)]
  when :gd
    write_sym = :gdImageGdPtr
    args = [ size ]
  when :gd2
    write_sym = :gdImageGd2Ptr
    args = [ options.delete(:chunk_size) || 0, options.delete(:fmt) || FMT_COMPRESSED, size ]
  else
    raise UnrecognizedImageTypeError,
      'Format (or file extension) is not recognized'
  end

  raise ArgumentError, "Unrecognized options #{options.inspect}" unless
    options.empty?

  File.open(filename, 'wb') do |file|
    begin
      img = GD2FFI.send(write_sym, image_ptr, *args)
      file.write(img.get_bytes(0, size.get_int(0)))
    ensure
      GD2FFI.gdFree(img)
    end
  end
end

#gdObject

Encode and return data for this image in “.gd” format. This is an internal format used by the gd library to quickly read and write images.



541
542
543
544
545
546
547
# File 'lib/gd2/image.rb', line 541

def gd
  size = FFI::MemoryPointer.new(:pointer)
  ptr = GD2FFI.send(:gdImageGdPtr, image_ptr, size)
  ptr.get_bytes(0, size.get_int(0))
ensure
  GD2FFI.send(:gdFree, ptr)
end

#gd2(fmt = FMT_COMPRESSED, chunk_size = 0) ⇒ Object

Encode and return data for this image in “.gd2” format. This is an internal format used by the gd library to quickly read and write images. The specified fmt may be either GD2::FMT_RAW or GD2::FMT_COMPRESSED.



552
553
554
555
556
557
558
# File 'lib/gd2/image.rb', line 552

def gd2(fmt = FMT_COMPRESSED, chunk_size = 0)
  size = FFI::MemoryPointer.new(:pointer)
  ptr = GD2FFI.send(:gdImageGd2Ptr, image_ptr, chunk_size.to_i, fmt.to_i, size)
  ptr.get_bytes(0, size.get_int(0))
ensure
  GD2FFI.send(:gdFree, ptr)
end

#get_pixel(x, y) ⇒ Object Also known as: pixel

Return the pixel value at image location (x, y).



299
300
301
# File 'lib/gd2/image.rb', line 299

def get_pixel(x, y)
  GD2FFI.send(:gdImageGetPixel, @image_ptr, x.to_i, y.to_i)
end

#gifObject

Encode and return data for this image in GIF format. Note that GIF only supports palette images; TrueColor images will be automatically converted to IndexedColor internally in order to create the GIF. Use Image#to_indexed_color to control this conversion more precisely.



519
520
521
522
523
524
525
# File 'lib/gd2/image.rb', line 519

def gif
  size = FFI::MemoryPointer.new(:pointer)
  ptr = GD2FFI.send(:gdImageGifPtr, image_ptr, size)
  ptr.get_bytes(0, size.get_int(0))
ensure
  GD2FFI.send(:gdFree, ptr)
end

#heightObject Also known as: h

Return the height of this image, in pixels.



282
283
284
# File 'lib/gd2/image.rb', line 282

def height
  image_ptr[:sy]
end

#init_with_image(ptr) ⇒ Object

:nodoc:



234
235
236
237
238
239
240
241
242
243
244
# File 'lib/gd2/image.rb', line 234

def init_with_image(ptr)  #:nodoc:
  @image_ptr = if ptr.is_a?(FFIStruct::ImagePtr)
    ptr
  else
    FFIStruct::ImagePtr.new(ptr)
  end

  @palette = self.class.palette_class.new(self) unless
    @palette && @palette.image == self
  self
end

#init_with_size(sx, sy) ⇒ Object

:nodoc:



230
231
232
# File 'lib/gd2/image.rb', line 230

def init_with_size(sx, sy)  #:nodoc:
  init_with_image self.class.create_image_ptr(sx, sy)
end

#inspectObject

:nodoc:



246
247
248
# File 'lib/gd2/image.rb', line 246

def inspect   #:nodoc:
  "#<#{self.class} #{size.inspect}>"
end

#interlaced=(bool) ⇒ Object

Set whether this image will be stored in interlaced form when output as PNG or JPEG.



351
352
353
# File 'lib/gd2/image.rb', line 351

def interlaced=(bool)
  GD2FFI.send(:gdImageInterlace, image_ptr, bool ? 1 : 0)
end

#interlaced?Boolean

Return true if this image will be stored in interlaced form when output as PNG or JPEG.

Returns:

  • (Boolean)


345
346
347
# File 'lib/gd2/image.rb', line 345

def interlaced?
  not image_ptr[:interlace].zero?
end

#jpeg(quality = nil) ⇒ Object

Encode and return data for this image in JPEG format. The quality argument should be in the range 0–95, with higher quality values usually implying both higher quality and larger sizes.



496
497
498
499
500
501
502
# File 'lib/gd2/image.rb', line 496

def jpeg(quality = nil)
  size = FFI::MemoryPointer.new(:pointer)
  ptr = GD2FFI.send(:gdImageJpegPtr, image_ptr, size, quality || -1)
  ptr.get_bytes(0, size.get_int(0))
ensure
  GD2FFI.send(:gdFree, ptr)
end

#merge_from(other, dst_x, dst_y, src_x, src_y, w, h, pct) ⇒ Object

Merge a portion of another image into this one by the amount specified as pct (a percentage). A percentage of 1.0 is identical to Image#copy_from; a percentage of 0.0 is a no-op. Note that alpha channel information from the source image is ignored.



590
591
592
593
594
# File 'lib/gd2/image.rb', line 590

def merge_from(other, dst_x, dst_y, src_x, src_y, w, h, pct)
  GD2FFI.send(:gdImageCopyMerge, image_ptr, other.image_ptr,
    dst_x.to_i, dst_y.to_i, src_x.to_i, src_y.to_i, w.to_i, h.to_i, pct.to_percent.round.to_i)
  self
end

#optimize_paletteObject

Consolidate duplicate colors in this image, and eliminate all unused palette entries. This only has an effect on IndexedColor images, and is rather expensive. Returns the number of palette entries deallocated.



436
437
438
# File 'lib/gd2/image.rb', line 436

def optimize_palette
  # implemented by subclass
end

#pixel2color(pixel) ⇒ Object

Return a Color object for the given pixel value.



334
335
336
# File 'lib/gd2/image.rb', line 334

def pixel2color(pixel)
  Color.new_from_rgba(pixel)
end

#png(level = nil) ⇒ Object

Encode and return data for this image in PNG format. The level argument should be in the range 0–9 indicating the level of lossless compression (0 = none, 1 = minimal but fast, 9 = best but slow).



507
508
509
510
511
512
513
# File 'lib/gd2/image.rb', line 507

def png(level = nil)
  size = FFI::MemoryPointer.new(:pointer)
  ptr = GD2FFI.send(:gdImagePngPtrEx, image_ptr, size, level.to_i || -1)
  ptr.get_bytes(0, size.get_int(0))
ensure
  GD2FFI.send(:gdFree, ptr)
end

#polar_transform(radius) ⇒ Object

Like Image#polar_transform! except a new image is returned.



667
668
669
# File 'lib/gd2/image.rb', line 667

def polar_transform(radius)
  clone.polar_transform!(radius)
end

#polar_transform!(radius) ⇒ Object

Transform this image into a new image of width and height radius × 2, in which the X axis of the original has been remapped to θ (angle) and the Y axis of the original has been remapped to ρ (distance from center). Note that the original image must be square.

Raises:



659
660
661
662
663
664
# File 'lib/gd2/image.rb', line 659

def polar_transform!(radius)
  raise 'Image must be square' unless width == height
  ptr = GD2FFI.send(:gdImageSquareToCircle, image_ptr, radius.to_i)
  raise LibraryError unless ptr
  init_with_image(ptr)
end

#resize(w, h, resample = true) ⇒ Object

Like Image#resize! except a new image is returned.



651
652
653
# File 'lib/gd2/image.rb', line 651

def resize(w, h, resample = true)
  clone.resize!(w, h, resample)
end

#resize!(w, h, resample = true) ⇒ Object

Resize this image to the given dimensions. If resample is true, the image pixels will be resampled; otherwise they will be stretched or shrunk as necessary without resampling.



640
641
642
643
644
645
646
647
648
# File 'lib/gd2/image.rb', line 640

def resize!(w, h, resample = true)
  ptr = self.class.create_image_ptr(w, h, false)
  GD2FFI.send(resample ? :gdImageCopyResampled : :gdImageCopyResized,
    ptr, image_ptr, 0, 0, 0, 0, w.to_i, h.to_i, width.to_i, height.to_i)
  alpha_blending = alpha_blending?
  init_with_image(ptr)
  self.alpha_blending = alpha_blending
  self
end

#rotate(angle, axis_x = width / 2.0, axis_y = height / 2.0) ⇒ Object

Like Image#rotate! except a new image is returned.



606
607
608
# File 'lib/gd2/image.rb', line 606

def rotate(angle, axis_x = width / 2.0, axis_y = height / 2.0)
  clone.rotate!(angle, axis_x, axis_y)
end

#rotate!(angle, axis_x = width / 2.0, axis_y = height / 2.0) ⇒ Object

Rotate this image by the given angle (in radians) about the given axis coordinates. Note that some of the edges of the image may be lost.



598
599
600
601
602
603
# File 'lib/gd2/image.rb', line 598

def rotate!(angle, axis_x = width / 2.0, axis_y = height / 2.0)
  ptr = self.class.create_image_ptr(width, height, alpha_blending?)
  GD2FFI.send(:gdImageCopyRotated, ptr, image_ptr,
    axis_x.to_f, axis_y.to_f, 0, 0, width.to_i, height.to_i, angle.to_degrees.round.to_i)
  init_with_image(ptr)
end

#save_alpha=(bool) ⇒ Object

Set whether this image will be stored with full alpha channel information when output as PNG.



377
378
379
# File 'lib/gd2/image.rb', line 377

def save_alpha=(bool)
  GD2FFI.send(:gdImageSaveAlpha, image_ptr, bool ? 1 : 0)
end

#save_alpha?Boolean

Return true if this image will be stored with full alpha channel information when output as PNG.

Returns:

  • (Boolean)


371
372
373
# File 'lib/gd2/image.rb', line 371

def save_alpha?
  not image_ptr[:saveAlphaFlag].zero?
end

#set_pixel(x, y, value) ⇒ Object

Set the pixel value at image location (x, y).



305
306
307
308
# File 'lib/gd2/image.rb', line 305

def set_pixel(x, y, value)
  GD2FFI.send(:gdImageSetPixel, @image_ptr, x.to_i, y.to_i, value.to_i)
  nil
end

#sharpen(pct) ⇒ Object

Sharpen this image by pct (a percentage) which can be greater than 1.0. Transparency/alpha channel are not altered. This has no effect on IndexedColor images.



674
675
676
# File 'lib/gd2/image.rb', line 674

def sharpen(pct)
  self
end

#sizeObject

Return the size of this image as an array [width, height], in pixels.



288
289
290
# File 'lib/gd2/image.rb', line 288

def size
  [width, height]
end

#to_indexed_color(colors = MAX_COLORS, dither = true) ⇒ Object

Return this image as an IndexedColor image, creating a copy if necessary. colors indicates the maximum number of palette colors to use, and dither controls whether dithering is used.

Raises:



686
687
688
689
690
691
692
693
694
695
696
697
698
699
# File 'lib/gd2/image.rb', line 686

def to_indexed_color(colors = MAX_COLORS, dither = true)
  ptr = GD2FFI.send(:gdImageCreatePaletteFromTrueColor,
    to_true_color.image_ptr, dither ? 1 : 0, colors.to_i)
  raise LibraryError unless ptr

  obj = IndexedColor.allocate.init_with_image(ptr)

  # fix for gd bug where image->open[] is not properly initialized
  (0...obj.image_ptr[:colorsTotal]).each do |i|
    obj.image_ptr[:open][i] = 0
  end

  obj
end

#to_true_colorObject

Return this image as a TrueColor image, creating a copy if necessary.



679
680
681
# File 'lib/gd2/image.rb', line 679

def to_true_color
  self
end

#transparentObject

Return the transparent color for this image, or nil if none has been set.



383
384
385
386
# File 'lib/gd2/image.rb', line 383

def transparent
  pixel = image_ptr[:transparent]
  pixel == -1 ? nil : pixel2color(pixel)
end

#transparent=(color) ⇒ Object

Set or unset the transparent color for this image.



389
390
391
392
# File 'lib/gd2/image.rb', line 389

def transparent=(color)
  GD2FFI.send(:gdImageColorTransparent, image_ptr,
    color.nil? ? -1 : color2pixel(color))
end

#true_color?Boolean

Return true if this image is a TrueColor image.

Returns:

  • (Boolean)


270
271
272
273
# File 'lib/gd2/image.rb', line 270

def true_color?
  kind_of?(TrueColor)
  # self.class.image_true_color?(image_ptr)
end

#uncrop(x1, y1 = x1, x2 = x1, y2 = y1) ⇒ Object

Like Image#uncrop! except a new image is returned.



633
634
635
# File 'lib/gd2/image.rb', line 633

def uncrop(x1, y1 = x1, x2 = x1, y2 = y1)
  clone.uncrop!(x1, y1, x2, y2)
end

#uncrop!(x1, y1 = x1, x2 = x1, y2 = y1) ⇒ Object

Expand the left, top, right, and bottom borders of this image by the given number of pixels.



625
626
627
628
629
630
# File 'lib/gd2/image.rb', line 625

def uncrop!(x1, y1 = x1, x2 = x1, y2 = y1)
  ptr = self.class.create_image_ptr(x1 + width + x2, y1 + height + y2,
    alpha_blending?)
  GD2FFI.send(:gdImageCopy, ptr, image_ptr, x1.to_i, y1.to_i, 0, 0, width.to_i, height.to_i)
  init_with_image(ptr)
end

#wbmp(fgcolor) ⇒ Object

Encode and return data for this image in WBMP format. WBMP currently supports only black and white images; the specified fgcolor will be used as the foreground color (black), and all other colors will be considered “background” (white).



531
532
533
534
535
536
537
# File 'lib/gd2/image.rb', line 531

def wbmp(fgcolor)
  size = FFI::MemoryPointer.new(:pointer)
  ptr = GD2FFI.send(:gdImageWBMPPtr, image_ptr, size, color2pixel(fgcolor))
  ptr.get_bytes(0, size.get_int(0))
ensure
  GD2FFI.send(:gdFree, ptr)
end

#widthObject Also known as: w

Return the width of this image, in pixels.



276
277
278
# File 'lib/gd2/image.rb', line 276

def width
  image_ptr[:sx]
end

#with_clipping(x1, y1, x2, y2) ⇒ Object

Temporarily set the clipping rectangle during the execution of a block. Pixels outside this rectangle will not be modified by drawing or copying operations.



409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/gd2/image.rb', line 409

def with_clipping(x1, y1, x2, y2)   #:yields: image
  clip = clipping
  begin
    p clipping
    GD2FFI.send(:gdImageSetClip, image_ptr, x1.to_i, y1.to_i, x2.to_i, y2.to_i)
    p clipping
    yield self
    self
  ensure
    GD2FFI.send(:gdImageSetClip, image_ptr, *clip)
  end
end