Class: Magick::Image

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/RMagick.rb,
lib/rmagick4j/image.rb

Overview

Ruby-level Magick::Image methods

Defined Under Namespace

Classes: Info, View

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(columns, rows, fill = nil, &info_block) ⇒ Image

Returns a new instance of Image.



194
195
196
197
198
# 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

Class Method Details

.allocate(*args, &add) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 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) ⇒ Object



4
5
6
7
# 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) ⇒ Object

Raises:

  • (ArgumentError)


15
16
17
18
19
20
# 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

.read(file, &add) ⇒ Object



9
10
11
12
13
# 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

Instance Method Details

#_imageObject



174
175
176
# File 'lib/rmagick4j/image.rb', line 174

def _image
  @image
end

#_image=(new_image) ⇒ Object



178
179
180
# File 'lib/rmagick4j/image.rb', line 178

def _image=(new_image)
  @image = new_image
end

#_infoObject



186
187
188
# File 'lib/rmagick4j/image.rb', line 186

def _info
  @info
end

#_info=(new_info) ⇒ Object



190
191
192
# File 'lib/rmagick4j/image.rb', line 190

def _info=(new_info)
  @info = new_info
end

#affinityObject



757
# File 'lib/RMagick.rb', line 757

alias_method :affinity, :remap

#annotate(draw, width, height, x, y, text, &block) ⇒ Object

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



761
762
763
764
765
# 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_colorObject



45
46
47
# File 'lib/rmagick4j/image.rb', line 45

def background_color
  @image.getBackgroundColor
end

#background_color=(value) ⇒ Object

Raises:

  • (TypeError)


49
50
51
52
53
# 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

#blurObject



55
56
57
# File 'lib/rmagick4j/image.rb', line 55

def blur
  @image.getBlur
end

#blur=(value) ⇒ Object

Raises:

  • (TypeError)


59
60
61
62
# 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) ⇒ Object



64
65
66
67
# 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) {|geometry.calculate_width(self._image), geometry.calculate_height(self._image), _self| ... } ⇒ Object

Yields:

  • (geometry.calculate_width(self._image), geometry.calculate_height(self._image), _self)

Yield Parameters:

  • _self (Magick::Image)

    the object that the method was called on



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# 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) ⇒ Object



89
90
91
# 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) ⇒ Object

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



783
784
785
# 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) ⇒ Object

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



776
777
778
779
# 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) ⇒ Object

Set the color at x,y



768
769
770
771
772
# 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) ⇒ Object

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



789
790
791
792
793
794
795
796
797
798
799
800
801
# 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

#columnsObject



93
94
95
# File 'lib/rmagick4j/image.rb', line 93

def columns
  @image.getWidth
end

#composite(*args) ⇒ Object



97
98
99
100
101
102
# 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

#copyObject



104
105
106
# File 'lib/rmagick4j/image.rb', line 104

def copy
  Image.from_image(@image.clone)
end

#crop(*args) ⇒ Object



108
109
110
# File 'lib/rmagick4j/image.rb', line 108

def crop(*args)
  copy.crop!(*args)
end

#crop!(*args) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# 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

#cur_imageObject

Used by ImageList methods - see ImageList#cur_image



804
805
806
# File 'lib/RMagick.rb', line 804

def cur_image
    self
end

#displayObject



143
144
145
146
# File 'lib/rmagick4j/image.rb', line 143

def display
  @image.display
  self
end

#each_iptc_datasetObject

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



866
867
868
869
870
871
872
873
874
875
# 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_pixelObject

Thanks to Russell Norris!



809
810
811
812
813
814
# 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) ⇒ Object



148
149
150
# File 'lib/rmagick4j/image.rb', line 148

def edge(radius=0.0)
  Image.from_image(Effects.EdgeEffect.new(radius).apply(_image))
end

#erase!Object



152
153
154
# File 'lib/rmagick4j/image.rb', line 152

def erase!
  @image.erase
end

#file_path(file) ⇒ Object



318
319
320
# File 'lib/rmagick4j/image.rb', line 318

def file_path(file)
  @image.file_path(file)
end

#file_type(file) ⇒ Object



314
315
316
# File 'lib/rmagick4j/image.rb', line 314

def file_type(file)
  @image.file_type(file)
end

#flipObject



165
166
167
# File 'lib/rmagick4j/image.rb', line 165

def flip
  copy.flip
end

#flip!Object



169
170
171
172
# File 'lib/rmagick4j/image.rb', line 169

def flip!
  @image.flip
  self
end

#formatObject



156
157
158
# File 'lib/rmagick4j/image.rb', line 156

def format
  @image.getFormat
end

#format=(format) ⇒ Object



160
161
162
163
# File 'lib/rmagick4j/image.rb', line 160

def format= format
  @image.setFormat(format)
  self
end

#get_exif_by_entry(*entry) ⇒ Object

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.



820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
# 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) ⇒ Object

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



838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
# 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) ⇒ Object

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



861
862
863
# File 'lib/RMagick.rb', line 861

def get_iptc_dataset(ds)
    self['IPTC:'+ds]
end

#implode(amount = 0.5) ⇒ Object



182
183
184
# 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) ⇒ Object

(Thanks to Al Evans for the suggestion.)



890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
# 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

#matteObject



200
201
202
# File 'lib/rmagick4j/image.rb', line 200

def matte
  @image.getMatte
end

#matte=(matte) ⇒ Object



204
205
206
# File 'lib/rmagick4j/image.rb', line 204

def matte= matte
  @image.setMatte(matte)
end

#matte_fill_to_border(x, y) ⇒ Object

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



944
945
946
947
948
949
# 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) ⇒ Object

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



935
936
937
938
939
940
941
# 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) ⇒ Object

Make the pixel at (x,y) transparent.



915
916
917
918
919
920
921
922
# 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) ⇒ Object

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



926
927
928
929
930
931
# 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!Object

Make all pixels transparent.



952
953
954
955
# File 'lib/RMagick.rb', line 952

def matte_reset!
    self.opacity = Magick::TransparentOpacity
    self
end

#negate(grayscale = false) ⇒ Object



208
209
210
# File 'lib/rmagick4j/image.rb', line 208

def negate(grayscale=false)
  Image.from_image(Effects.NegateEffect.new(grayscale).apply(_image))
end

#normalizeObject



212
213
214
# 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) ⇒ Object



216
217
218
# 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) ⇒ Object



220
221
222
# File 'lib/rmagick4j/image.rb', line 220

def raise(width=6, height=6, raise=true)
  Image.from_image(@image.raised(width, height, raise))
end

#remapObject



224
225
226
# File 'lib/rmagick4j/image.rb', line 224

def remap
	# TODO: Implement. Just here to avoid warning in RMagick 2.9 file.
end

#resample(x_res = 72.0, y_res = nil) ⇒ Object

Corresponds to ImageMagick’s -resample option



958
959
960
961
962
963
964
965
# 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) ⇒ Object



228
229
230
# File 'lib/rmagick4j/image.rb', line 228

def resize(*args)
  copy.resize!(*args)
end

#resize!(*args) ⇒ Object



232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# 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) ⇒ Object Also known as: crop_resized

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



969
970
971
# File 'lib/RMagick.rb', line 969

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

#resize_to_fill!(ncols, nrows = nil, gravity = CenterGravity) ⇒ Object Also known as: crop_resized!



973
974
975
976
977
978
979
980
981
# 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

#resize_to_fit(cols, rows = nil) ⇒ Object

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



989
990
991
992
993
994
# 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) ⇒ Object



996
997
998
999
1000
1001
# 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) ⇒ Object



248
249
250
# File 'lib/rmagick4j/image.rb', line 248

def rotate(amount, qualifier=nil)
  copy.rotate!(amount,qualifier)
end

#rotate!(amount, qualifier = nil) ⇒ Object



252
253
254
255
256
257
258
259
260
261
262
263
264
265
# 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

#rowsObject



267
268
269
# File 'lib/rmagick4j/image.rb', line 267

def rows
  @image.getHeight
end

#shade(shading = false, azimuth = 30, elevation = 30) ⇒ Object



271
272
273
# 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) ⇒ Object



275
276
277
# 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) ⇒ Object

Raises:

  • (IndexError)


279
280
281
282
283
# 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) ⇒ Object

Replace neighboring pixels to border color with texture pixels



1010
1011
1012
# 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) ⇒ Object

Replace matching neighboring pixels with texture pixels



1004
1005
1006
1007
# 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) ⇒ Object



285
286
287
288
289
# 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) ⇒ Object

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



1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
# 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) ⇒ Object



291
292
293
294
295
296
297
298
299
300
# 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) ⇒ Object



302
303
304
# 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) ⇒ Object



306
307
308
309
310
311
312
# 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