class Magick::Image

Ruby-level Magick::Image methods

def annotate(draw, width, height, x, y, text, &block)

want to find it in this class.
Provide an alternate version of Draw#annotate, for folks who
def annotate(draw, width, height, x, y, text, &block)
  check_destroyed
  draw.annotate(self, width, height, x, y, text, &block)
  self
end

def color_fill_to_border(x, y, fill)

to the fill color
Set all pixels that are neighbors of x,y and are not the border color
def color_fill_to_border(x, y, fill)
  color_flood_fill(border_color, fill, x, y, Magick::FillToBorderMethod)
end

def color_floodfill(x, y, fill)

are neighbors to the fill color
Set all pixels that have the same color as the pixel at x,y and
def color_floodfill(x, y, fill)
  target = pixel_color(x, y)
  color_flood_fill(target, fill, x, y, Magick::FloodfillMethod)
end

def color_point(x, y, fill)

Set the color at x,y
def color_point(x, y, fill)
  f = copy
  f.pixel_color(x, y, fill)
  f
end

def color_reset!(fill)

Accepts either String or Pixel arguments
Set all pixels to the fill color. Very similar to Image#erase!
def color_reset!(fill)
  save = background_color
  # Change the background color _outside_ the begin block
  # so that if this object is frozen the exeception will be
  # raised before we have to handle it explicitly.
  self.background_color = fill
  begin
    erase!
  ensure
    self.background_color = save
  end
  self
end

def cur_image

Used by ImageList methods - see ImageList#cur_image
def cur_image
  self
end

def each_iptc_dataset

Iterate over IPTC record number:dataset tags, yield for each non-nil dataset
def each_iptc_dataset
  Magick::IPTC.constants.each do |record|
    rec = Magick::IPTC.const_get(record)
    rec.constants.each do |dataset|
      data_field = get_iptc_dataset(rec.const_get(dataset))
      yield(dataset, data_field) unless data_field.nil?
    end
  end
  nil
end

def each_pixel

Thanks to Russell Norris!
def each_pixel
  get_pixels(0, 0, columns, rows).each_with_index do |p, n|
    yield(p, n % columns, n / columns)
  end
  self
end

def get_exif_by_entry(*entry)

arrays.
return all entries and values. The return value is an array of [name,value]
return the values associated with the entries. If no entries specified,
Retrieve EXIF data by entry or all. If one or more entry names specified,
def get_exif_by_entry(*entry)
  ary = []
  if entry.empty?
    exif_data = self['EXIF:*']
    exif_data&.split("\n")&.each { |exif| ary.push(exif.split('=')) }
  else
    get_exif_by_entry # ensure properties is populated with exif data
    entry.each do |name|
      rval = self["EXIF:#{name}"]
      ary.push([name, rval])
    end
  end
  ary
end

def get_exif_by_number(*tag)

Retrieve EXIF data by tag number or all tag/value pairs. The return value is a hash.
def get_exif_by_number(*tag)
  hash = {}
  if tag.empty?
    exif_data = self['EXIF:!']
    exif_data&.split("\n")&.each do |exif|
      tag, value = exif.split('=')
      tag = tag[1, 4].hex
      hash[tag] = value
    end
  else
    get_exif_by_number # ensure properties is populated with exif data
    tag.each do |num|
      rval = self[sprintf('#%04X', num.to_i)]
      hash[num] = rval == 'unknown' ? nil : rval
    end
  end
  hash
end

def get_iptc_dataset(ds)

Magick::IPTC, above.
Retrieve IPTC information by record number:dataset tag constant defined in
def get_iptc_dataset(ds)
  self['IPTC:' + ds]
end

def level(black_point = 0.0, white_point = nil, gamma = nil)

(Thanks to Al Evans for the suggestion.)
def level(black_point = 0.0, white_point = nil, gamma = nil)
  black_point = Float(black_point)
  white_point ||= Magick::QuantumRange - black_point
  white_point = Float(white_point)
  gamma_arg = gamma
  gamma ||= 1.0
  gamma = Float(gamma)
  if gamma.abs > 10.0 || white_point.abs <= 10.0 || white_point.abs < gamma.abs
    gamma, white_point = white_point, gamma
    white_point = Magick::QuantumRange - black_point unless gamma_arg
  end
  level2(black_point, white_point, gamma)
end

def matte_fill_to_border(x, y)

Make transparent any neighbor pixel that is not the border color.
def matte_fill_to_border(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  f.matte_flood_fill(border_color, x, y, FillToBorderMethod, alpha: TransparentAlpha)
end

def matte_floodfill(x, y)

at (x,y) and is a neighbor.
Make transparent any pixel that matches the color of the pixel
def matte_floodfill(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  target = f.pixel_color(x, y)
  f.matte_flood_fill(target, x, y, FloodfillMethod, alpha: TransparentAlpha)
end

def matte_point(x, y)

Make the pixel at (x,y) transparent.
def matte_point(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  pixel = f.pixel_color(x, y)
  pixel.alpha = TransparentAlpha
  f.pixel_color(x, y, pixel)
  f
end

def matte_replace(x, y)

pixel at (x, y).
Make transparent all pixels that are the same color as the
def matte_replace(x, y)
  f = copy
  f.alpha(OpaqueAlphaChannel) unless f.alpha?
  target = f.pixel_color(x, y)
  f.transparent(target)
end

def matte_reset!

Make all pixels transparent.
def matte_reset!
  alpha(TransparentAlphaChannel)
  self
end

def resize_to_fill(ncols, nrows = nil, gravity = CenterGravity)

Resize and crop if necessary. (Thanks to Jerett Taylor!)
Force an image to exact dimensions without changing the aspect ratio.
def resize_to_fill(ncols, nrows = nil, gravity = CenterGravity)
  copy.resize_to_fill!(ncols, nrows, gravity)
end

def resize_to_fill!(ncols, nrows = nil, gravity = CenterGravity)

def resize_to_fill!(ncols, nrows = nil, gravity = CenterGravity)
  nrows ||= ncols
  if ncols != columns || nrows != rows
    scale = [ncols / columns.to_f, nrows / rows.to_f].max
    resize!(scale * columns + 0.5, scale * rows + 0.5)
  end
  crop!(gravity, ncols, nrows, true) if ncols != columns || nrows != rows
  self
end

def resize_to_fit(cols, rows = nil)

(Thanks to Robert Manni!)
Convenience method to resize retaining the aspect ratio.
def resize_to_fit(cols, rows = nil)
  rows ||= cols
  change_geometry(Geometry.new(cols, rows)) do |ncols, nrows|
    resize(ncols, nrows)
  end
end

def resize_to_fit!(cols, rows = nil)

def resize_to_fit!(cols, rows = nil)
  rows ||= cols
  change_geometry(Geometry.new(cols, rows)) do |ncols, nrows|
    resize!(ncols, nrows)
  end
end

def texture_fill_to_border(x, y, texture)

Replace neighboring pixels to border color with texture pixels
def texture_fill_to_border(x, y, texture)
  texture_flood_fill(border_color, texture, x, y, FillToBorderMethod)
end

def texture_floodfill(x, y, texture)

Replace matching neighboring pixels with texture pixels
def texture_floodfill(x, y, texture)
  target = pixel_color(x, y)
  texture_flood_fill(target, texture, x, y, FloodfillMethod)
end

def view(x, y, width, height)

object, otherwise return the view object.
Construct a view. If a block is present, yield and pass the view
def view(x, y, width, height)
  view = View.new(self, x, y, width, height)
  return view unless block_given?
  begin
    yield(view)
  ensure
    view.sync
  end
  nil
end