class Magick::Image

Ruby-level Magick::Image methods

Public Class Methods

allocate(*args, &add) click to toggle source
# File lib/rmagick4j/image.rb, line 22
def self.allocate(*args, &add)
  info = Info.new(&add)
  if args.length == 1
    case args[0]
    when String then
      # TODO Respect Dir.getwd
      name = args[0]
      @image = Magick4J.ImageDatabase.createDefault(name, info._info) || Magick4J.MagickImage.new(java.io.File.new(name))
    when Magick4J.MagickImage then
      @image = args[0]
    when Image then
      @image = args[0]._image
    else
      raise ArgumentError, "The argument just can be a String, a MagickImage or an Image instance."
    end
  else
    @image = Magick4J.MagickImage.new(args[0], args[1], info._info)
    if args.length == 3
      args[2].fill(self)
    end
  end
end
from_blob(blob, &add) click to toggle source
# File lib/rmagick4j/image.rb, line 4
def self.from_blob(blob, &add)
  # TODO multiple images in file
  [Image.from_image(Magick4J.MagickImage.from_blob(blob.to_java_bytes), &add)]
end
from_image(image, &add) click to toggle source
# File lib/rmagick4j/image.rb, line 15
def self.from_image(image, &add)
  raise ArgumentError, 'First parameter must be a MagickImage instance.' unless image.is_a? Magick4J.MagickImage
  magick_image = Image.new(image.getWidth(), image.getHeight(), &add)
  magick_image._image = image
  magick_image
end
new(columns, rows, fill=nil, &info_block) click to toggle source
# File lib/rmagick4j/image.rb, line 194
def initialize(columns, rows, fill=nil, &info_block)
  info = Info.new(&info_block)
  @image = Magick4J.MagickImage.new(columns, rows, info._info)
  fill.fill(self) if fill.respond_to? :fill
end
read(file, &add) click to toggle source
# File lib/rmagick4j/image.rb, line 9
def self.read(file, &add)
  info = Info.new(&add)
  image = Magick4J.ImageDatabase.createDefault(file.to_s, info._info) || Magick4J.MagickImage.new(java.io.File.new(file.to_s))
  [Image.from_image(image,&add)]
end

Public Instance Methods

_image() click to toggle source
# File lib/rmagick4j/image.rb, line 174
def _image
  @image
end
_image=(new_image) click to toggle source
# File lib/rmagick4j/image.rb, line 178
def _image=(new_image)
  @image = new_image
end
_info() click to toggle source
# File lib/rmagick4j/image.rb, line 186
def _info
  @info
end
_info=(new_info) click to toggle source
# File lib/rmagick4j/image.rb, line 190
def _info=(new_info)
  @info = new_info
end
affinity()
Alias for: remap
annotate(draw, width, height, x, y, text, &block) click to toggle source

Provide an alternate version of Draw#annotate, for folks who want to find it in this class.

# File lib/RMagick.rb, line 761
def annotate(draw, width, height, x, y, text, &block)
  check_destroyed
  draw.annotate(self, width, height, x, y, text, &block)
  self
end
background_color() click to toggle source
# File lib/rmagick4j/image.rb, line 45
def background_color
  @image.getBackgroundColor
end
background_color=(value) click to toggle source
# File lib/rmagick4j/image.rb, line 49
def background_color=(value)
  raise TypeError, "argument must be color name or pixel (#{value.class} given)" unless value.is_a?(String) || value.is_a?(Pixel)
  value = Pixel.from_color(value) if value.is_a?(String)
  @image.setBackgroundColor(value)
end
blur() click to toggle source
# File lib/rmagick4j/image.rb, line 55
def blur
  @image.getBlur
end
blur=(value) click to toggle source
# File lib/rmagick4j/image.rb, line 59
def blur=(value)
  raise TypeError, "no implicit conversion to float from #{value.class.to_s.downcase}" unless value.is_a? Numeric
  @image.setBlur(value)
end
blur_image(radius=0.0, sigma=1.0) click to toggle source
# File lib/rmagick4j/image.rb, line 64
def blur_image(radius=0.0, sigma=1.0)
  # Swap order on purpose. I wanted them the other way around in Magick4J.
  Image.from_image(Effects.BlurEffect.new(radius,sigma).apply(_image))
end
change_geometry(geometry) { |calculate_width, calculate_height, self| ... } click to toggle source
# File lib/rmagick4j/image.rb, line 69
def change_geometry(geometry)
  geometry = Geometry.from_s(geometry.to_s) unless geometry.is_a? Geometry
  index = if geometry.flag.nil?
            0
          else
            geometry.flag._val
          end
  width_distance = geometry.width.nil? ? 
    JRelativeWidthDistance.new : 
    JWidthDistances[index].new(geometry.width)
  height_distance = geometry.height.nil? ? 
    JRelativeHeightDistance.new : 
    JHeightDistances[index].new(geometry.height)
  geometry = JGeometry.new(width_distance, height_distance, 
                           geometry.x, geometry.y)      
  yield geometry.calculate_width(self._image),
        geometry.calculate_height(self._image),
        self
end
charcoal(radius=0.0, sigma=1.0) click to toggle source
# File lib/rmagick4j/image.rb, line 89
def charcoal(radius=0.0, sigma=1.0)
  Image.from_image(Effects.CharcoalEffect.new(radius,sigma).apply(_image))
end
color_fill_to_border(x, y, fill) click to toggle source

Set all pixels that are neighbors of x,y and are not the border color to the fill color

# File lib/RMagick.rb, line 783
def color_fill_to_border(x, y, fill)
    color_flood_fill(border_color, fill, x, y, Magick::FillToBorderMethod)
end
color_floodfill(x, y, fill) click to toggle source

Set all pixels that have the same color as the pixel at x,y and are neighbors to the fill color

# File lib/RMagick.rb, line 776
def color_floodfill(x, y, fill)
    target = pixel_color(x, y)
    color_flood_fill(target, fill, x, y, Magick::FloodfillMethod)
end
color_point(x, y, fill) click to toggle source

Set the color at x,y

# File lib/RMagick.rb, line 768
def color_point(x, y, fill)
    f = copy
    f.pixel_color(x, y, fill)
    return f
end
color_reset!(fill) click to toggle source

Set all pixels to the fill color. Very similar to Image#erase! Accepts either String or Pixel arguments

# File lib/RMagick.rb, line 789
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
columns() click to toggle source
# File lib/rmagick4j/image.rb, line 93
def columns
  @image.getWidth
end
composite(*args) click to toggle source
# File lib/rmagick4j/image.rb, line 97
def composite(*args)
  # image, x, y, composite_op
  args[0] = args[0]._image
  args.map! {|arg| arg.is_a?(Enum) ? arg._val : arg}
  Image.from_image(@image.composited(*args))
end
copy() click to toggle source
# File lib/rmagick4j/image.rb, line 104
def copy
  Image.from_image(@image.clone)
end
crop(*args) click to toggle source
# File lib/rmagick4j/image.rb, line 108
def crop(*args)
  copy.crop!(*args)
end
crop!(*args) click to toggle source
# File lib/rmagick4j/image.rb, line 112
def crop!(*args)
  # gravity, x, y, width, height, reset_offset
  # Defaults.
  gravity = nil
  x = y = -1
  reset_offset = false
  # Find available args.
  if args.first.is_a? GravityType
    gravity = args.shift._val
  end
  if [FalseClass, TrueClass].member? args.last.class
    reset = args.pop
  end
  if args.length == 4
    x, y = args[0..1]
  end
  width, height = args[-2..-1]
  # Call Java.
  # TODO Why wouldn't we reset offset information? Do we need to use that?
  @image =  unless gravity.nil?
              if x == -1 || y == -1
                @image.crop(gravity, width, height)
              else
                @image.crop(gravity, x, y, width, height)
              end
            else
              @image.crop(x,y,width,height)
            end
  self
end
crop_resized(ncols, nrows=nil, gravity=CenterGravity)

Preserve aliases used < RMagick 2.0.1

Alias for: resize_to_fill
crop_resized!(ncols, nrows=nil, gravity=CenterGravity)
Alias for: resize_to_fill!
cur_image() click to toggle source

Used by ImageList methods - see ImageList#cur_image

# File lib/RMagick.rb, line 804
def cur_image
    self
end
display() click to toggle source
# File lib/rmagick4j/image.rb, line 143
def display
  @image.display
  self
end
each_iptc_dataset() { |dataset, data_field| ... } click to toggle source

Iterate over IPTC record number:dataset tags, yield for each non-nil dataset

# File lib/RMagick.rb, line 866
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
each_pixel() { |p, n%columns, n/columns| ... } click to toggle source

Thanks to Russell Norris!

# File lib/RMagick.rb, line 809
def each_pixel
  get_pixels(0, 0, columns, rows).each_with_index do |p, n|
    yield(p, n%columns, n/columns)
  end
  self
end
edge(radius=0.0) click to toggle source
# File lib/rmagick4j/image.rb, line 148
def edge(radius=0.0)
  Image.from_image(Effects.EdgeEffect.new(radius).apply(_image))
end
erase!() click to toggle source
# File lib/rmagick4j/image.rb, line 152
def erase!
  @image.erase
end
file_path(file) click to toggle source
# File lib/rmagick4j/image.rb, line 318
def file_path(file)
  @image.file_path(file)
end
file_type(file) click to toggle source
# File lib/rmagick4j/image.rb, line 314
def file_type(file)
  @image.file_type(file)
end
flip() click to toggle source
# File lib/rmagick4j/image.rb, line 165
def flip
  copy.flip
end
flip!() click to toggle source
# File lib/rmagick4j/image.rb, line 169
def flip!
  @image.flip
  self
end
format() click to toggle source
# File lib/rmagick4j/image.rb, line 156
def format
  @image.getFormat
end
format=(format) click to toggle source
# File lib/rmagick4j/image.rb, line 160
def format= format
  @image.setFormat(format)
  self
end
get_exif_by_entry(*entry) click to toggle source

Retrieve EXIF data by entry or all. If one or more entry names specified, return the values associated with the entries. If no entries specified, return all entries and values. The return value is an array of [name,value] arrays.

# File lib/RMagick.rb, line 820
def get_exif_by_entry(*entry)
    ary = Array.new
    if entry.length == 0
        exif_data = self['EXIF:*']
        if exif_data
            exif_data.split("\n").each { |exif| ary.push(exif.split('=')) }
        end
    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
    return ary
end
get_exif_by_number(*tag) click to toggle source

Retrieve EXIF data by tag number or all tag/value pairs. The return value is a hash.

# File lib/RMagick.rb, line 838
def get_exif_by_number(*tag)
    hash = Hash.new
    if tag.length == 0
        exif_data = self['EXIF:!']
        if exif_data
            exif_data.split("\n").each do |exif|
                tag, value = exif.split('=')
                tag = tag[1,4].hex
                hash[tag] = value
            end
        end
    else
        get_exif_by_number()    # ensure properties is populated with exif data
        tag.each do |num|
            rval = self['#%04X' % num.to_i]
            hash[num] = rval == 'unknown' ? nil : rval
        end
    end
    return hash
end
get_iptc_dataset(ds) click to toggle source

Retrieve IPTC information by record number:dataset tag constant defined in Magick::IPTC, above.

# File lib/RMagick.rb, line 861
def get_iptc_dataset(ds)
    self['IPTC:'+ds]
end
implode(amount=0.5) click to toggle source
# File lib/rmagick4j/image.rb, line 182
def implode(amount=0.5)
  Image.from_image(Effects.ImplodeEffect.new(amount).apply(_image))
end
level(black_point=0.0, white_point=nil, gamma=nil) click to toggle source

(Thanks to Al Evans for the suggestion.)

# File lib/RMagick.rb, line 890
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
        unless gamma_arg
            white_point = Magick::QuantumRange - black_point
        end
    end

    return level2(black_point, white_point, gamma)
end
matte() click to toggle source
# File lib/rmagick4j/image.rb, line 200
def matte
  @image.getMatte
end
matte=(matte) click to toggle source
# File lib/rmagick4j/image.rb, line 204
def matte= matte
  @image.setMatte(matte)
end
matte_fill_to_border(x, y) click to toggle source

Make transparent any neighbor pixel that is not the border color.

# File lib/RMagick.rb, line 944
def matte_fill_to_border(x, y)
    f = copy
    f.opacity = Magick::OpaqueOpacity unless f.matte
    f.matte_flood_fill(border_color, TransparentOpacity,
                       x, y, FillToBorderMethod)
end
matte_floodfill(x, y) click to toggle source

Make transparent any pixel that matches the color of the pixel at (x,y) and is a neighbor.

# File lib/RMagick.rb, line 935
def matte_floodfill(x, y)
    f = copy
    f.opacity = OpaqueOpacity unless f.matte
    target = f.pixel_color(x, y)
    f.matte_flood_fill(target, TransparentOpacity,
                       x, y, FloodfillMethod)
end
matte_point(x, y) click to toggle source

Make the pixel at (x,y) transparent.

# File lib/RMagick.rb, line 915
def matte_point(x, y)
    f = copy
    f.opacity = OpaqueOpacity unless f.matte
    pixel = f.pixel_color(x,y)
    pixel.opacity = TransparentOpacity
    f.pixel_color(x, y, pixel)
    return f
end
matte_replace(x, y) click to toggle source

Make transparent all pixels that are the same color as the pixel at (x, y).

# File lib/RMagick.rb, line 926
def matte_replace(x, y)
    f = copy
    f.opacity = OpaqueOpacity unless f.matte
    target = f.pixel_color(x, y)
    f.transparent(target)
end
matte_reset!() click to toggle source

Make all pixels transparent.

# File lib/RMagick.rb, line 952
def matte_reset!
    self.opacity = Magick::TransparentOpacity
    self
end
negate(grayscale=false) click to toggle source
# File lib/rmagick4j/image.rb, line 208
def negate(grayscale=false)
  Image.from_image(Effects.NegateEffect.new(grayscale).apply(_image))
end
normalize() click to toggle source
# File lib/rmagick4j/image.rb, line 212
def normalize
  Image.from_image(Effects.NormalizeEffect.new().apply(_image))
end
quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false) click to toggle source
# File lib/rmagick4j/image.rb, line 216
def quantize(number_colors=256, colorspace=RGBColorspace, dither=true, tree_depth=0, measure_error=false)
  Image.from_image(@image.quantized(number_colors, colorspace._val, dither, tree_depth, measure_error))
end
raise(width=6, height=6, raise=true) click to toggle source
# File lib/rmagick4j/image.rb, line 220
def raise(width=6, height=6, raise=true)
  Image.from_image(@image.raised(width, height, raise))
end
remap() click to toggle source
# File lib/rmagick4j/image.rb, line 224
def remap
        # TODO: Implement. Just here to avoid warning in RMagick 2.9 file.
end
Also aliased as: affinity
resample(x_res=72.0, y_res=nil) click to toggle source

Corresponds to ImageMagick's -resample option

# File lib/RMagick.rb, line 958
def resample(x_res=72.0, y_res=nil)
    y_res ||= x_res
    width = x_res * columns / x_resolution + 0.5
    height = y_res * rows / y_resolution + 0.5
    self.x_resolution = x_res
    self.y_resolution = y_res
    resize(width, height)
end
resize(*args) click to toggle source
# File lib/rmagick4j/image.rb, line 228
def resize(*args)
  copy.resize!(*args)
end
resize!(*args) click to toggle source
# File lib/rmagick4j/image.rb, line 232
def resize!(*args)
  @image =  if args.length == 1
              @image.resized(args[0])
            elsif args.length == 2 # It must be 4 nor 2, but two of them are not yet implemented
              # TODO  Implement the other two arguments.
              # arg[0] --> new_width
              # arg[1] --> new_height
              # arg[2] --> filter=LanczosFilter
              # arg[3] --> support=1.0
              @image.resized(args[0],args[1])
            else
              Kernel.raise ArgumentError, "wrong number of parameters(#{args.length} for 1 or 4)"
            end
  self
end
resize_to_fill(ncols, nrows=nil, gravity=CenterGravity) click to toggle source

Force an image to exact dimensions without changing the aspect ratio. Resize and crop if necessary. (Thanks to Jerett Taylor!)

# File lib/RMagick.rb, line 969
def resize_to_fill(ncols, nrows=nil, gravity=CenterGravity)
    copy.resize_to_fill!(ncols, nrows, gravity)
end
Also aliased as: crop_resized
resize_to_fill!(ncols, nrows=nil, gravity=CenterGravity) click to toggle source
# File lib/RMagick.rb, line 973
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
Also aliased as: crop_resized!
resize_to_fit(cols, rows=nil) click to toggle source

Convenience method to resize retaining the aspect ratio. (Thanks to Robert Manni!)

# File lib/RMagick.rb, line 989
def resize_to_fit(cols, rows=nil)
    rows ||= cols
    change_geometry(Geometry.new(cols, rows)) do |ncols, nrows|
        resize(ncols, nrows)
    end
end
resize_to_fit!(cols, rows=nil) click to toggle source
# File lib/RMagick.rb, line 996
def resize_to_fit!(cols, rows=nil)
    rows ||= cols
    change_geometry(Geometry.new(cols, rows)) do |ncols, nrows|
        resize!(ncols, nrows)
    end
end
rotate(amount, qualifier=nil) click to toggle source
# File lib/rmagick4j/image.rb, line 248
def rotate(amount, qualifier=nil)
  copy.rotate!(amount,qualifier)
end
rotate!(amount, qualifier=nil) click to toggle source
# File lib/rmagick4j/image.rb, line 252
def rotate!(amount, qualifier=nil)
  if qualifier == '<' && columns < rows
    @image.rotate(amount)
    self
  elsif qualifier == '>' && columns > rows
    @image.rotate(amount)
    self
  elsif qualifier.nil?
    @image.rotate(amount)
    self
  else
    nil
  end
end
rows() click to toggle source
# File lib/rmagick4j/image.rb, line 267
def rows
  @image.getHeight
end
shade(shading=false,azimuth=30,elevation=30) click to toggle source
# File lib/rmagick4j/image.rb, line 271
def shade(shading=false,azimuth=30,elevation=30)
  Image.from_image(Effects.ShadeEffect.new(shading,azimuth,elevation).apply(_image))
end
solarize(threshold=50) click to toggle source
# File lib/rmagick4j/image.rb, line 275
def solarize(threshold=50)
  Image.from_image(Effects.SolarizeEffect.new(threshold).apply(_image))
end
store_pixels(x, y, columns, rows, pixels) click to toggle source
# File lib/rmagick4j/image.rb, line 279
def store_pixels(x, y, columns, rows, pixels)
  ria_size = columns*rows
  raise IndexError, "not enough elements in array - expecting #{ria_size}, got #{pixels.size}" if pixels.size < ria_size
  @image.storePixels(x,y,columns,rows,pixels.to_java)
end
texture_fill_to_border(x, y, texture) click to toggle source

Replace neighboring pixels to border color with texture pixels

# File lib/RMagick.rb, line 1010
def texture_fill_to_border(x, y, texture)
    texture_flood_fill(border_color, texture, x, y, FillToBorderMethod)
end
texture_floodfill(x, y, texture) click to toggle source

Replace matching neighboring pixels with texture pixels

# File lib/RMagick.rb, line 1004
def texture_floodfill(x, y, texture)
    target = pixel_color(x, y)
    texture_flood_fill(target, texture, x, y, FloodfillMethod)
end
to_blob(&add) click to toggle source
# File lib/rmagick4j/image.rb, line 285
def to_blob(&add)
  info = Info.new(&add)
  @image.setFormat(info.format) if info.format
  String.from_java_bytes(@image.toBlob)
end
view(x, y, width, height) { |view| ... } click to toggle source

Construct a view. If a block is present, yield and pass the view object, otherwise return the view object.

# File lib/RMagick.rb, line 1016
def view(x, y, width, height)
    view = View.new(self, x, y, width, height)

    if block_given?
        begin
            yield(view)
        ensure
            view.sync
        end
        return nil
    else
        return view
    end
end
watermark(mark, lightness=1.0, saturation=1.0, gravity=nil, x_offset=0, y_offset=0) click to toggle source
# File lib/rmagick4j/image.rb, line 291
def watermark(mark, lightness=1.0, saturation=1.0, gravity=nil, x_offset=0, y_offset=0)
  if gravity.is_a? Numeric
    # gravity is technically an optional argument in the middle.
    gravity = nil
    y_offset = x_offset
    x_offset = gravity
  end
  # TODO Perform watermark.
  self
end
wave(amplitude=25.0, wavelength=150.0) click to toggle source
# File lib/rmagick4j/image.rb, line 302
def wave(amplitude=25.0, wavelength=150.0)
  Image.from_image(Effects.WaveEffect.new(amplitude,wavelength).apply(_image))
end
write(file, &add) click to toggle source
# File lib/rmagick4j/image.rb, line 306
def write(file, &add)
  # TODO I'm having trouble finding out how this info is used, so I'll skip using it for now.
  info = Info.new(&add)
  # TODO Resolve pwd as needed
  @image.write(file)
  self
end