Class: EventedMagick::Image

Inherits:
Object
  • Object
show all
Defined in:
lib/evented_magick.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input_path, tempfile = nil) ⇒ Image

Instance Methods




41
42
43
44
45
46
47
48
49
50
# File 'lib/evented_magick.rb', line 41

def initialize(input_path, tempfile=nil)
  @path = input_path
  @tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected.
  @method = defined?(::EM) && EM.reactor_running? ? :evented_execute : :blocking_execute

  # Ensure that the file is an image
  output = run_command("identify", "-format", format_option("%m %w %h"), @path)
  (format, width, height) = output.split
  @values = { 'format' => format, 'width' => width.to_i, 'height' => height.to_i, 'dimensions' => [width.to_i, height.to_i] }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(symbol, *args) ⇒ Object

If an unknown method is called then it is sent through the morgrify program Look here to find all the commands (www.imagemagick.org/script/mogrify.php)



109
110
111
112
113
# File 'lib/evented_magick.rb', line 109

def method_missing(symbol, *args)
  args.push(@path) # push the path onto the end
  run_command("mogrify", "-#{symbol}", *args)
  self
end

Instance Attribute Details

#outputObject (readonly)

Returns the value of attribute output.



13
14
15
# File 'lib/evented_magick.rb', line 13

def output
  @output
end

#pathObject (readonly)

Returns the value of attribute path.



11
12
13
# File 'lib/evented_magick.rb', line 11

def path
  @path
end

#tempfileObject (readonly)

Returns the value of attribute tempfile.



12
13
14
# File 'lib/evented_magick.rb', line 12

def tempfile
  @tempfile
end

Class Method Details

.from_blob(blob, ext = nil) ⇒ Object



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/evented_magick.rb', line 18

def from_blob(blob, ext = nil)
  begin
    tempfile = Tempfile.new(['evented_magick', ext.to_s])
    tempfile.binmode
    tempfile.write(blob)
  ensure
    tempfile.close if tempfile
  end

  return self.new(tempfile.path, tempfile)
end

.open(image_path) ⇒ Object Also known as: from_file

Use this if you don’t want to overwrite the image file



31
32
33
34
35
# File 'lib/evented_magick.rb', line 31

def open(image_path)
  File.open(image_path, "rb") do |f|
    self.from_blob(f.read, File.extname(image_path))
  end
end

Instance Method Details

#<<(*args) ⇒ Object

Sends raw commands to imagemagick’s mogrify command. The image path is automatically appended to the command



64
65
66
# File 'lib/evented_magick.rb', line 64

def <<(*args)
  run_command("mogrify", *args << @path)
end

#[](value) ⇒ Object



53
54
55
56
57
58
59
60
61
# File 'lib/evented_magick.rb', line 53

def [](value)
  key = value.to_s
  return @values[key] if %w(format width height dimensions).include? key
  if key == "size"
    File.size(@path)
  else
    run_command('identify', '-format', "\"#{key}\"", @path).split("\n")[0]
  end
end

#blocking_execute(cmd) ⇒ Object



161
162
163
164
# File 'lib/evented_magick.rb', line 161

def blocking_execute(cmd)
  output = `#{cmd}`
  [output, $?]
end

#combine_options(&block) ⇒ Object

You can use multiple commands together using this method



116
117
118
119
120
# File 'lib/evented_magick.rb', line 116

def combine_options(&block)
  c = CommandBuilder.new
  block.call c
  run_command("mogrify", *c.args << @path)
end

#evented_execute(cmd) ⇒ Object



152
153
154
155
156
157
158
159
# File 'lib/evented_magick.rb', line 152

def evented_execute(cmd)
  fiber = Fiber.current
  EM::system(cmd) do |output, status|
    fiber.resume([output, status])
  end
  
  Fiber.yield
end

#format(format, page = 0) ⇒ Object

This is a ‘special’ command because it needs to change @path to reflect the new extension Formatting an animation into a non-animated type will result in ImageMagick creating multiple pages (starting with 0). You can choose which page you want to manipulate. We default to the first page.



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/evented_magick.rb', line 72

def format(format, page=0)
  run_command("mogrify", "-format", format, @path)

  old_path = @path.dup
  @path.sub!(/(\.\w+)?$/, ".#{format}")
  File.delete(old_path) unless old_path == @path

  unless File.exists?(@path)
    begin
      FileUtils.copy_file(@path.sub(".#{format}", "-#{page}.#{format}"), @path)
    rescue e
      raise MiniMagickError, "Unable to format to #{format}; #{e}" unless File.exist?(@path)
    end
  end
ensure
  Dir[@path.sub(/(\.\w+)?$/, "-[0-9]*.#{format}")].each do |fname|
    File.unlink(fname)
  end
end

#format_option(format) ⇒ Object

Outputs a carriage-return delimited format string for Unix and Windows



128
129
130
# File 'lib/evented_magick.rb', line 128

def format_option(format)
  windows? ? "#{format}\\n" : "#{format}\\\\n"
end

#run_command(command, *args) ⇒ Object



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/evented_magick.rb', line 132

def run_command(command, *args)
  full_args = args.collect do |arg|        
    # args can contain characters like '>' so we must escape them, but don't quote switches
    if arg !~ /^[\+\-]/
      "\"#{arg}\""
    else
      arg.to_s
    end
  end.join(' ')

  full_cmd = "#{command} #{full_args}"
  (output, status) = send(@method, full_cmd)

  if status.exitstatus == 0
    output
  else
    raise MiniMagickError, "ImageMagick command (#{full_cmd.inspect}) failed: #{{:status_code => status, :output => output}.inspect}"
  end
end

#to_blobObject

Give you raw data back



99
100
101
102
103
104
105
# File 'lib/evented_magick.rb', line 99

def to_blob
  f = File.new @path
  f.binmode
  f.read
ensure
  f.close if f
end

#windows?Boolean

Check to see if we are running on win32 – we need to escape things differently

Returns:

  • (Boolean)


123
124
125
# File 'lib/evented_magick.rb', line 123

def windows?
  !(RUBY_PLATFORM =~ /win32/).nil?
end

#write(output_path) ⇒ Object

Writes the temporary image that we are using for processing to the output path



93
94
95
96
# File 'lib/evented_magick.rb', line 93

def write(output_path)
  FileUtils.copy_file @path, output_path
  run_command "identify", output_path # Verify that we have a good image
end