Class: Gluttonberg::Library::QuickMagick::Image

Inherits:
Object
  • Object
show all
Defined in:
lib/gluttonberg/library/quick_magick/image.rb

Constant Summary collapse

IMAGE_SETTINGS_METHODS =

Image settings supported by ImageMagick

%w{
  adjoin affine alpha authenticate attenuate background bias black-point-compensation
  blue-primary bordercolor caption channel colors colorspace comment compose compress define
  delay depth display dispose dither encoding endian family fill filter font format fuzz gravity
  green-primary intent interlace interpolate interword-spacing kerning label limit loop mask
  mattecolor monitor orient ping pointsize preview quality quiet red-primary regard-warnings
  remap respect-parentheses scene seed stretch stroke strokewidth style taint texture treedepth
  transparent-color undercolor units verbose view virtual-pixel weight white-point

  density page sampling-factor size tile-offset
}
IMAGE_OPERATORS_METHODS =

Image operators supported by ImageMagick

%w{
alpha auto-orient bench black-threshold bordercolor charcoal clip clip-mask clip-path colorize
contrast convolve cycle decipher deskew despeckle distort edge encipher emboss enhance equalize
evaluate flip flop function gamma identify implode layers level level-colors median modulate monochrome
negate noise normalize opaque ordered-dither NxN paint polaroid posterize print profile quantize
radial-blur Raise random-threshold recolor render rotate segment sepia-tone set shade solarize
sparse-color spread strip swirl threshold tile tint transform transparent transpose transverse trim
type unique-colors white-threshold

adaptive-blur adaptive-resize adaptive-sharpen annotate blur border chop contrast-stretch extent
extract frame gaussian-blur geometry lat linear-stretch liquid-rescale motion-blur region repage
resample resize roll sample scale selective-blur shadow sharpen shave shear sigmoidal-contrast
sketch splice thumbnail unsharp vignette wave
      
append average clut coalesce combine composite deconstruct flatten fx hald-clut morph mosaic process reverse separate write
crop
}
WITH_EQUAL_METHODS =

methods that are called with (=)

%w{alpha background bias black-point-compensation blue-primary border bordercolor caption
cahnnel colors colorspace comment compose compress depth density encoding endian family fill filter
font format frame fuzz geometry gravity label mattecolor page pointsize quality stroke strokewidth
undercolor units weight
brodercolor transparent type size}
WITH_GEOMETRY_METHODS =

methods that takes geometry options

%w{density page sampling-factor size tile-offset adaptive-blur adaptive-resize adaptive-sharpen
annotate blur border chop contrast-stretch extent extract frame gaussian-blur
geometry lat linear-stretch liquid-rescale motion-blur region repage resample resize roll
sample scale selective-blur shadow sharpen shave shear sigmoidal-contrast sketch
splice thumbnail unsharp vignette wave crop}
SPECIAL_COMMANDS =

Methods that need special treatment. This array is used just to keep track of them.

%w{floodfill antialias draw}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(filename, index = 0, info_line = nil, pseudo_image = false) ⇒ Image

constructor



203
204
205
206
207
208
209
210
211
212
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 203

def initialize(filename, index=0, info_line=nil, pseudo_image=false)
  @image_filename = filename
  @index = index
  @pseudo_image = pseudo_image
  if info_line
    @image_infoline = info_line.split
    @image_infoline[0..1] = @image_infoline[0..1].join(' ') while @image_infoline.size > 1 && !@image_infoline[0].start_with?(image_filename)
  end
  @arguments = ""
end

Instance Attribute Details

#image_filenameObject (readonly) Also known as: original_filename

define attribute readers (getters)



199
200
201
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 199

def image_filename
  @image_filename
end

Class Method Details

.from_blob(blob, &proc) ⇒ Object

create an array of images from the given blob data



12
13
14
15
16
17
18
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 12

def from_blob(blob, &proc)
  file = Tempfile.new(QuickMagick::random_string)
  file.binmode
  file.write(blob)
  file.close
  self.read(file.path, &proc)
end

.gradient(width, height, type = QuickMagick::LinearGradient, color1 = nil, color2 = nil) {|i| ... } ⇒ Object

Creates a new image initially set to gradient Default gradient is linear gradient from black to white

Yields:

  • (i)


36
37
38
39
40
41
42
43
44
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 36

def gradient(width, height, type=QuickMagick::LinearGradient, color1=nil, color2=nil)
  template_name = type + ":"
  template_name << color1.to_s if color1
  template_name << '-' << color2.to_s if color2
  i = self.new(template_name, 0, nil, true)
  i.size = QuickMagick::geometry(width, height)
  yield(i) if block_given?
  i
end

.identify(filename) ⇒ Object

returns info for an image using identify command



67
68
69
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 67

def identify(filename)
  QuickMagick.exec3 "identify #{QuickMagick.c filename}"
end

.pattern(width, height, pattern) {|i| ... } ⇒ Object

Creates an image from pattern

Yields:

  • (i)

Raises:



57
58
59
60
61
62
63
64
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 57

def pattern(width, height, pattern)
  raise QuickMagick::QuickMagickError, "Invalid pattern '#{pattern.to_s}'" unless QuickMagick::Patterns.include?(pattern.to_s)
  template_name = "pattern:#{pattern.to_s}"
  i = self.new(template_name, 0, nil, true)
  i.size = QuickMagick::geometry(width, height)
  yield(i) if block_given?
  i
end

.read(filename, &proc) ⇒ Object Also known as: open

create an array of images from the given file



21
22
23
24
25
26
27
28
29
30
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 21

def read(filename, &proc)
  info = identify(%Q<"#{filename}">)
  info_lines = info.split(/[\r\n]/)
  images = []
  info_lines.each_with_index do |info_line, i|
    images << Image.new("#{filename}", i, info_line)
  end
  images.each(&proc) if block_given?
  return images
end

.solid(width, height, color = nil) {|i| ... } ⇒ Object

Creates an image with solid color

Yields:

  • (i)


47
48
49
50
51
52
53
54
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 47

def solid(width, height, color=nil)
  template_name = QuickMagick::SolidColor+":"
  template_name << color.to_s if color
  i = self.new(template_name, 0, nil, true)
  i.size = QuickMagick::geometry(width, height)
  yield(i) if block_given?
  i
end

Instance Method Details

#animateObject

displays the current image as animated image



460
461
462
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 460

def animate
  `animate #{command_line}`
end

#antialias=(flag) ⇒ Object

Enables/Disables flood fill. Pass a boolean argument.



194
195
196
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 194

def antialias=(flag)
	append_basic flag ? '-antialias' : '+antialias'
end

#append_basic(arg) ⇒ Object

append the given string as is. Used to append special arguments like antialias or debug



81
82
83
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 81

def append_basic(arg)
  @arguments << arg << ' '
end

#append_to_operators(arg, value = nil) ⇒ Object

append the given option, value pair to the args for the current image



99
100
101
102
103
104
105
106
107
108
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 99

def append_to_operators(arg, value=nil)
  is_draw = (arg == 'draw')
  if @last_is_draw && is_draw
    @arguments.insert(@arguments.rindex('"'), " #{value}")
  else
    @arguments << %Q<-#{arg} #{QuickMagick.c value} >
  end
  @last_is_draw = is_draw
  self
end

#append_to_settings(arg, value = nil) ⇒ Object

append the given option, value pair to the settings of the current image



74
75
76
77
78
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 74

def append_to_settings(arg, value=nil)
  @arguments << "-#{arg} #{QuickMagick.c value} "
  @last_is_draw = false
  self
end

#argumentsObject



413
414
415
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 413

def arguments
  @arguments
end

#bit_depthObject

Bit depth



436
437
438
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 436

def bit_depth
  image_infoline[4].to_i
end

#colorsObject

Number of different colors used in this image



441
442
443
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 441

def colors
  image_infoline[6].to_i
end

#columnsObject Also known as: width

columns of image in pixels



422
423
424
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 422

def columns
  image_infoline[2].split('x').first.to_i
end

#command_lineObject

The command line so far that will be used to convert or save the image



215
216
217
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 215

def command_line
  %Q< "(" #{@arguments} #{QuickMagick.c(image_filename + (@pseudo_image ? "" : "[#{@index}]"))} ")" >
end

#displayObject

displays the current image to the x-windowing system



465
466
467
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 465

def display
  `display #{command_line}`
end

#draw_arc(x0, y0, x1, y1, a0, a1, options = {}) ⇒ Object

The arc primitive is used to inscribe an elliptical segment in to a given rectangle. An arc requires the two corners used for rectangle (see above) followed by the start and end angles of the arc of the segment segment (e.g. 130,30 200,100 45,90). The start and end points produced are then joined with a line segment and the resulting segment of an ellipse is filled.



296
297
298
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 296

def draw_arc(x0, y0, x1, y1, a0, a1, options={})
  append_to_operators("draw", "#{options_to_str(options)} arc #{x0},#{y0} #{x1},#{y1} #{a0},#{a1}")
end

#draw_bezier(points, options = {}) ⇒ Object

The Bezier primitive creates a spline curve and requires three or points to define its shape. The first and last points are the knots and these points are attained by the curve, while any intermediate coordinates are control points. If two control points are specified, the line between each end knot and its sequentially respective control point determines the tangent direction of the curve at that end. If one control point is specified, the lines from the end knots to the one control point determines the tangent directions of the curve at each end. If more than two control points are specified, then the additional control points act in combination to determine the intermediate shape of the curve. In order to draw complex curves, it is highly recommended either to use the path primitive or to draw multiple four-point bezier segments with the start and end knots of each successive segment repeated.



341
342
343
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 341

def draw_bezier(points, options={})
  append_to_operators("draw", "#{options_to_str(options)} bezier #{points_to_str(points)}")
end

#draw_circle(x0, y0, x1, y1, options = {}) ⇒ Object

The circle primitive makes a disk (filled) or circle (unfilled). Give the center and any point on the perimeter (boundary).



308
309
310
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 308

def draw_circle(x0, y0, x1, y1, options={})
  append_to_operators("draw", "#{options_to_str(options)} circle #{x0},#{y0} #{x1},#{y1}")
end

#draw_ellipse(x0, y0, rx, ry, a0, a1, options = {}) ⇒ Object

Use ellipse to draw a partial (or whole) ellipse. Give the center point, the horizontal and vertical “radii” (the semi-axes of the ellipse) and start and end angles in degrees (e.g. 100,100 100,150 0,360).



303
304
305
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 303

def draw_ellipse(x0, y0, rx, ry, a0, a1, options={})
  append_to_operators("draw", "#{options_to_str(options)} ellipse #{x0},#{y0} #{rx},#{ry} #{a0},#{a1}")
end

#draw_image(operator, x0, y0, w, h, image_filename, options = {}) ⇒ Object

Use image to composite an image with another image. Follow the image keyword with the composite operator, image location, image size, and filename You can use 0,0 for the image size, which means to use the actual dimensions found in the image header. Otherwise, it is scaled to the given dimensions. See -compose for a description of the composite operators.



360
361
362
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 360

def draw_image(operator, x0, y0, w, h, image_filename, options={})
  append_to_operators("draw", "#{options_to_str(options)} image #{operator} #{x0},#{y0} #{w},#{h} \"#{image_filename}\"")
end

#draw_line(x0, y0, x1, y1, options = {}) ⇒ Object

draws a line between the given two points A line primitive requires a start point and end point.



274
275
276
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 274

def draw_line(x0, y0, x1, y1, options={})
  append_to_operators("draw", "#{options_to_str(options)} line #{x0},#{y0} #{x1},#{y1}")
end

#draw_path(path_spec, options = {}) ⇒ Object

A path represents an outline of an object, defined in terms of moveto (set a new current point), lineto (draw a straight line), curveto (draw a Bezier curve), arc (elliptical or circular arc) and closepath (close the current shape by drawing a line to the last moveto) elements. Compound paths (i.e., a path with subpaths, each consisting of a single moveto followed by one or more line or curve operations) are possible to allow effects such as donut holes in objects. (See www.w3.org/TR/SVG/paths.html)



352
353
354
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 352

def draw_path(path_spec, options={})
  append_to_operators("draw", "#{options_to_str(options)} path #{path_spec}")
end

#draw_point(x, y, options = {}) ⇒ Object

draws a point at the given location in pixels A point primitive is specified by a single point in the pixel plane, that is, by an ordered pair of integer coordinates, x,y. (As it involves only a single pixel, a point primitive is not affected by -stroke or -strokewidth.)



268
269
270
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 268

def draw_point(x, y, options={})
  append_to_operators("draw", "#{options_to_str(options)} point #{x},#{y}")
end

#draw_polygon(points, options = {}) ⇒ Object

The polygon primitive requires three or more points to define their perimeters. A polyline is simply a polygon in which the final point is not stroked to the start point. When unfilled, this is a polygonal line. If the -stroke setting is none (the default), then a polyline is identical to a polygon.

points - A single array with each pair forming a coordinate in the form (x, y).

e.g. [0,0,100,100,100,0] will draw a polygon between points (0,0)-(100,100)-(100,0)



326
327
328
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 326

def draw_polygon(points, options={})
  append_to_operators("draw", "#{options_to_str(options)} polygon #{points_to_str(points)}")
end

#draw_polyline(points, options = {}) ⇒ Object

The polyline primitive requires three or more points to define their perimeters. A polyline is simply a polygon in which the final point is not stroked to the start point. When unfilled, this is a polygonal line. If the -stroke setting is none (the default), then a polyline is identical to a polygon.

points - A single array with each pair forming a coordinate in the form (x, y).

e.g. [0,0,100,100,100,0] will draw a polyline between points (0,0)-(100,100)-(100,0)



317
318
319
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 317

def draw_polyline(points, options={})
  append_to_operators("draw", "#{options_to_str(options)} polyline #{points_to_str(points)}")
end

#draw_rectangle(x0, y0, x1, y1, options = {}) ⇒ Object

draw a rectangle with the given two corners A rectangle primitive is specified by the pair of points at the upper left and lower right corners.



280
281
282
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 280

def draw_rectangle(x0, y0, x1, y1, options={})
  append_to_operators("draw", "#{options_to_str(options)} rectangle #{x0},#{y0} #{x1},#{y1}")
end

#draw_round_rectangle(x0, y0, x1, y1, wc, hc, options = {}) ⇒ Object

draw a rounded rectangle with the given two corners wc and hc are the width and height of the arc A roundRectangle primitive takes the same corner points as a rectangle followed by the width and height of the rounded corners to be removed.



288
289
290
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 288

def draw_round_rectangle(x0, y0, x1, y1, wc, hc, options={})
  append_to_operators("draw", "#{options_to_str(options)} roundRectangle #{x0},#{y0} #{x1},#{y1} #{wc},#{hc}")
end

#draw_text(x0, y0, text, options = {}) ⇒ Object

Use text to annotate an image with text. Follow the text coordinates with a string.



365
366
367
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 365

def draw_text(x0, y0, text, options={})
  append_to_operators("draw", "#{options_to_str(options)} text #{x0},#{y0} '#{text}'")
end

#floodfill(width, height = nil, x = nil, y = nil, flag = nil, color = nil) ⇒ Object

Fills a rectangle with a solid color



189
190
191
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 189

def floodfill(width, height=nil, x=nil, y=nil, flag=nil, color=nil)
  append_to_operators "floodfill", QuickMagick::geometry(width, height, x, y, flag), color
end

#formatObject

image file format



417
418
419
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 417

def format
  image_infoline[1]
end

#get_pixel(x, y) ⇒ Object

Reads a pixel from the image. WARNING: This is done through command line which is very slow. It is not recommended at all to use this method for image processing for example.



453
454
455
456
457
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 453

def get_pixel(x, y)
  result = QuickMagick.exec3("identify -verbose -crop #{QuickMagick::geometry(1,1,x,y)} #{QuickMagick.c image_filename}[#{@index}]")
  result =~ /Histogram:\s*\d+:\s*\(\s*(\d+),\s*(\d+),\s*(\d+)\)/
  return [$1.to_i, $2.to_i, $3.to_i]
end

#image_infolineObject

An information line about the image obtained using ‘identify’ command line



220
221
222
223
224
225
226
227
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 220

def image_infoline
  return nil if @pseudo_image
  unless @image_infoline
    @image_infoline = QuickMagick::Image::identify(command_line).split
    @image_infoline[0..1] = @image_infoline[0..1].join(' ') while @image_infoline.size > 1 && !@image_infoline[0].start_with?(image_filename)
  end
  @image_infoline
end

#options_to_str(options) ⇒ Object

converts options passed to any primitive to a string that can be passed to ImageMagick options allowed are:

  • rotate degrees

  • translate dx,dy

  • scale sx,sy

  • skewX degrees

  • skewY degrees

  • gravity NorthWest, North, NorthEast, West, Center, East, SouthWest, South, or SouthEast

  • stroke color

  • fill color

The rotate primitive rotates subsequent shape primitives and text primitives about the origin of the main image. If you set the region before the draw command, the origin for transformations is the upper left corner of the region. The translate primitive translates subsequent shape and text primitives. The scale primitive scales them. The skewX and skewY primitives skew them with respect to the origin of the main image or the region. The text gravity primitive only affects the placement of text and does not interact with the other primitives. It is equivalent to using the gravity method, except that it is limited in scope to the draw_text option in which it appears.



246
247
248
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 246

def options_to_str(options)
  options.to_a.flatten.join " "
end

#points_to_str(points) ⇒ Object

Converts an array of coordinates to a string that can be passed to polygon, polyline and bezier



251
252
253
254
255
256
257
258
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 251

def points_to_str(points)
  raise QuickMagick::QuickMagickError, "Points must be an even number of coordinates" if points.size.odd?
  points_str = ""
  points.each_slice(2) do |point|
    points_str << point.join(",") << " "
  end
  points_str
end

#revert!Object

Reverts this image to its last saved state. Note that you cannot revert an image created from scratch.



112
113
114
115
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 112

def revert!
  raise QuickMagick::QuickMagickError, "Cannot revert a pseudo image" if @pseudo_image
  @arguments = ""
end

#rowsObject Also known as: height

rows of image in pixels



429
430
431
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 429

def rows
  image_infoline[2].split('x').last.to_i
end

#save(output_filename) ⇒ Object Also known as: write, convert

saves the current image to the given filename



370
371
372
373
374
375
376
377
378
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 370

def save(output_filename)
  result = QuickMagick.exec3 "convert #{command_line} #{QuickMagick.c output_filename} "#-quality 92" 
	if @pseudo_image
		# since it's been saved, convert it to normal image (not pseudo)
		initialize(output_filename)
 	revert!
	end
  return result 
end

#save!Object Also known as: write!, mogrify!

saves the current image overwriting the original image file



384
385
386
387
388
389
390
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 384

def save!
  raise QuickMagick::QuickMagickError, "Cannot mogrify a pseudo image" if @pseudo_image
  result = QuickMagick.exec3 "mogrify #{command_line}"
  # remove all operations to avoid duplicate operations
  revert!
  return result 
end

#sizeObject

returns size of image in bytes



446
447
448
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 446

def size
  File.size?(image_filename)
end

#to_blobObject



395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
# File 'lib/gluttonberg/library/quick_magick/image.rb', line 395

def to_blob
	tmp_file = Tempfile.new(QuickMagick::random_string)
	if command_line =~ /-format\s(\S+)\s/
		# use format set up by user
		blob_format = $1
	elsif !@pseudo_image
		# use original image format
		blob_format = self.format
	else
	# default format is jpg
	blob_format = 'jpg'
	end
	save "#{blob_format}:#{tmp_file.path}"
	blob = nil
	File.open(tmp_file.path, 'rb') { |f| blob = f.read}
	blob
end