class Magick::ImageList
Attributes
Public Class Methods
Initialize new instances
# File lib/rmagick_internal.rb, line 1551 def initialize(*filenames, &block) @images = [] @scene = nil filenames.each do |f| Magick::Image.read(f, &block).each { |n| @images << n } end @scene = length - 1 if length > 0 # last image in array end
Public Instance Methods
# File lib/rmagick_internal.rb, line 1316 def *(other) Kernel.raise ArgumentError, "Integer required (#{other.class} given)" unless other.is_a? Integer current = get_current ilist = self.class.new (@images * other).each { |image| ilist << image } ilist.set_current current ilist end
# File lib/rmagick_internal.rb, line 1325 def <<(obj) assert_image obj @images << obj @scene = @images.length - 1 self end
Compare ImageLists Compare each image in turn until the result of a comparison is not 0. If all comparisons return 0, then
return if A.scene != B.scene return A.length <=> B.length
# File lib/rmagick_internal.rb, line 1337 def <=>(other) return unless other.is_a? self.class size = [length, other.length].min size.times do |x| r = self[x] <=> other[x] return r unless r.zero? end return 0 if @scene.nil? && other.scene.nil? return if @scene.nil? && !other.scene.nil? return if !@scene.nil? && other.scene.nil? r = scene <=> other.scene return r unless r.zero? length <=> other.length end
# File lib/rmagick_internal.rb, line 1356 def [](*args) a = @images[*args] if a.respond_to?(:each) ilist = self.class.new a.each { |image| ilist << image } a = ilist end a end
# File lib/rmagick_internal.rb, line 1366 def []=(*args) obj = @images.[]=(*args) if obj.respond_to?(:each) assert_image_array(obj) set_current obj.last.__id__ elsif obj assert_image(obj) set_current obj.__id__ else set_current nil end end
Ensure respond_to? answers correctly when we are delegating to Image
# File lib/rmagick_internal.rb, line 1396 def clear @scene = nil @images.clear end
# File lib/rmagick_internal.rb, line 1401 def clone ditto = dup ditto.freeze if frozen? ditto end
override Enumerable#collect
# File lib/rmagick_internal.rb, line 1408 def collect(&block) current = get_current a = @images.map(&block) ilist = self.class.new a.each { |image| ilist << image } ilist.set_current current ilist end
# File lib/rmagick_internal.rb, line 1417 def collect!(&block) @images.map!(&block) assert_image_array @images self end
# File lib/rmagick_internal.rb, line 1446 def compact current = get_current ilist = self.class.new a = @images.compact a.each { |image| ilist << image } ilist.set_current current ilist end
# File lib/rmagick_internal.rb, line 1455 def compact! current = get_current a = @images.compact! # returns nil if no changes were made set_current current a.nil? ? nil : self end
# File lib/rmagick_internal.rb, line 1462 def concat(other) assert_image_array other other.each { |image| @images << image } @scene = length - 1 self end
Make a deep copy
# File lib/rmagick_internal.rb, line 1424 def copy ditto = self.class.new @images.each { |f| ditto << f.copy } ditto.scene = @scene ditto end
Return the current image
# File lib/rmagick_internal.rb, line 1432 def cur_image Kernel.raise IndexError, 'no images in this list' unless @scene @images[@scene] end
Set same delay for all images
# File lib/rmagick_internal.rb, line 1470 def delay=(d) raise ArgumentError, 'delay must be greater than or equal to 0' if Integer(d) < 0 @images.each { |f| f.delay = Integer(d) } end
# File lib/rmagick_internal.rb, line 1476 def delete(obj, &block) assert_image obj current = get_current a = @images.delete(obj, &block) set_current current a end
# File lib/rmagick_internal.rb, line 1484 def delete_at(ndx) current = get_current a = @images.delete_at(ndx) set_current current a end
# File lib/rmagick_internal.rb, line 1491 def delete_if(&block) current = get_current @images.delete_if(&block) set_current current self end
# File lib/rmagick_internal.rb, line 1809 def destroy! @images.each(&:destroy!) self end
# File lib/rmagick_internal.rb, line 1814 def destroyed? @images.all?(&:destroyed?) end
# File lib/rmagick_internal.rb, line 1498 def dup ditto = self.class.new @images.each { |img| ditto << img } ditto.scene = @scene ditto end
# File lib/rmagick_internal.rb, line 1505 def eql?(other) begin assert_image_array other rescue ArgumentError return false end eql = other.eql?(@images) begin # "other" is another ImageList eql &&= @scene == other.scene rescue NoMethodError # "other" is a plain Array end eql end
# File lib/rmagick_internal.rb, line 1521 def fill(*args, &block) assert_image args[0] unless block current = get_current @images.fill(*args, &block) assert_image_array self set_current current self end
Override Enumerable’s find_all
# File lib/rmagick_internal.rb, line 1531 def find_all(&block) current = get_current a = @images.select(&block) ilist = self.class.new a.each { |image| ilist << image } ilist.set_current current ilist end
# File lib/rmagick_internal.rb, line 1541 def from_blob(*blobs, &block) Kernel.raise ArgumentError, 'no blobs given' if blobs.empty? blobs.each do |b| Magick::Image.from_blob(b, &block).each { |n| @images << n } end @scene = length - 1 self end
# File lib/rmagick_internal.rb, line 1561 def insert(index, *args) args.each { |image| assert_image image } current = get_current @images.insert(index, *args) set_current current self end
Call inspect for all the images
# File lib/rmagick_internal.rb, line 1570 def inspect img = @images.map(&:inspect) '[' + img.join(",\n") + "]\nscene=#{@scene}" end
Set the number of iterations of an animated GIF
# File lib/rmagick_internal.rb, line 1576 def iterations=(n) n = Integer(n) Kernel.raise ArgumentError, 'iterations must be between 0 and 65535' if n < 0 || n > 65_535 @images.each { |f| f.iterations = n } end
# File lib/rmagick_internal.rb, line 1582 def last(*args) if args.empty? a = @images.last else a = @images.last(*args) ilist = self.class.new a.each { |img| ilist << img } @scene = a.length - 1 a = ilist end a end
Custom marshal/unmarshal for Ruby 1.8.
# File lib/rmagick_internal.rb, line 1596 def marshal_dump ary = [@scene] @images.each { |i| ary << Marshal.dump(i) } ary end
# File lib/rmagick_internal.rb, line 1602 def marshal_load(ary) @scene = ary.shift @images = [] ary.each { |a| @images << Marshal.load(a) } end
The ImageList
class supports the Magick::Image
class methods by simply sending the method to the current image. If the method isn’t explicitly supported, send it to the current image in the array. If there are no images, send it up the line. Catch a NameError and emit a useful message.
# File lib/rmagick_internal.rb, line 1612 def method_missing(meth_id, *args, &block) if @scene img = @images[@scene] new_img = img.public_send(meth_id, *args, &block) img.equal?(new_img) ? self : new_img else super end rescue NoMethodError Kernel.raise NoMethodError, "undefined method `#{meth_id.id2name}' for #{self.class}" rescue Exception $ERROR_POSITION.delete_if { |s| /:in `send'$/.match(s) || /:in `method_missing'$/.match(s) } Kernel.raise end
Create a new image and add it to the end
# File lib/rmagick_internal.rb, line 1628 def new_image(cols, rows, *fill, &info_blk) self << Magick::Image.new(cols, rows, *fill, &info_blk) end
# File lib/rmagick_internal.rb, line 1632 def partition(&block) a = @images.partition(&block) t = self.class.new a[0].each { |img| t << img } t.set_current nil f = self.class.new a[1].each { |img| f << img } f.set_current nil [t, f] end
Ping files and concatenate the new images
# File lib/rmagick_internal.rb, line 1644 def ping(*files, &block) Kernel.raise ArgumentError, 'no files given' if files.empty? files.each do |f| Magick::Image.ping(f, &block).each { |n| @images << n } end @scene = length - 1 self end
# File lib/rmagick_internal.rb, line 1653 def pop current = get_current a = @images.pop # can return nil set_current current a end
# File lib/rmagick_internal.rb, line 1660 def push(*objs) objs.each do |image| assert_image image @images << image end @scene = length - 1 self end
Read files and concatenate the new images
# File lib/rmagick_internal.rb, line 1670 def read(*files, &block) Kernel.raise ArgumentError, 'no files given' if files.empty? files.each do |f| Magick::Image.read(f, &block).each { |n| @images << n } end @scene = length - 1 self end
override Enumerable’s reject
# File lib/rmagick_internal.rb, line 1680 def reject(&block) current = get_current ilist = self.class.new a = @images.reject(&block) a.each { |image| ilist << image } ilist.set_current current ilist end
# File lib/rmagick_internal.rb, line 1689 def reject!(&block) current = get_current a = @images.reject!(&block) @images = a unless a.nil? set_current current a.nil? ? nil : self end
# File lib/rmagick_internal.rb, line 1697 def replace(other) assert_image_array other current = get_current @images.clear other.each { |image| @images << image } @scene = length.zero? ? nil : 0 set_current current self end
# File lib/rmagick_internal.rb, line 1709 def respond_to?(meth_id, priv = false) return true if __respond_to__?(meth_id, priv) if @scene @images[@scene].respond_to?(meth_id, priv) else super end end
# File lib/rmagick_internal.rb, line 1719 def reverse current = get_current a = self.class.new @images.reverse_each { |image| a << image } a.set_current current a end
# File lib/rmagick_internal.rb, line 1727 def reverse! current = get_current @images.reverse! set_current current self end
# File lib/rmagick_internal.rb, line 1734 def reverse_each(&block) @images.reverse_each(&block) self end
Allow scene to be set to nil
# File lib/rmagick_internal.rb, line 1286 def scene=(n) if n.nil? Kernel.raise IndexError, 'scene number out of bounds' unless @images.empty? @scene = nil return elsif @images.empty? Kernel.raise IndexError, 'scene number out of bounds' end n = Integer(n) Kernel.raise IndexError, 'scene number out of bounds' if n < 0 || n > length - 1 @scene = n end
# File lib/rmagick_internal.rb, line 1739 def shift current = get_current a = @images.shift set_current current a end
# File lib/rmagick_internal.rb, line 1746 def slice(*args) slice = @images.slice(*args) if slice ilist = self.class.new if slice.respond_to?(:each) slice.each { |image| ilist << image } else ilist << slice end else ilist = nil end ilist end
# File lib/rmagick_internal.rb, line 1761 def slice!(*args) current = get_current a = @images.slice!(*args) set_current current a end
# File lib/rmagick_internal.rb, line 1391 def sort!(*args, &block) @images.sort!(*args, &block) self end
# File lib/rmagick_internal.rb, line 1768 def ticks_per_second=(t) Kernel.raise ArgumentError, 'ticks_per_second must be greater than or equal to 0' if Integer(t) < 0 @images.each { |f| f.ticks_per_second = Integer(t) } end
# File lib/rmagick_internal.rb, line 1773 def to_a @images.map { |image| image } end
# File lib/rmagick_internal.rb, line 1777 def uniq current = get_current a = self.class.new @images.uniq.each { |image| a << image } a.set_current current a end
# File lib/rmagick_internal.rb, line 1785 def uniq!(*_args) current = get_current a = @images.uniq! set_current current a.nil? ? nil : self end
@scene -> new object
# File lib/rmagick_internal.rb, line 1793 def unshift(obj) assert_image obj @images.unshift(obj) @scene = 0 self end
Protected Instance Methods
# File lib/rmagick_internal.rb, line 1251 def assert_image(obj) Kernel.raise ArgumentError, "Magick::Image required (#{obj.class} given)" unless obj.is_a? Magick::Image end
Ensure array is always an array of Magick::Image
objects
# File lib/rmagick_internal.rb, line 1256 def assert_image_array(ary) Kernel.raise ArgumentError, "Magick::ImageList or array of Magick::Images required (#{ary.class} given)" unless ary.respond_to? :each ary.each { |obj| assert_image obj } end
Find old current image, update scene number current is the id of the old current image.
# File lib/rmagick_internal.rb, line 1263 def set_current(current) if length.zero? self.scene = nil return # Don't bother looking for current image elsif scene.nil? || scene >= length self.scene = length - 1 return elsif !current.nil? # Find last instance of "current" in the list. # If "current" isn't in the list, set current to last image. self.scene = length - 1 each_with_index do |f, i| self.scene = i if f.__id__ == current end return end self.scene = length - 1 end
Private Instance Methods
# File lib/rmagick_internal.rb, line 1243 def get_current @images[@scene].__id__ rescue StandardError nil end