Class: MiniMagick::Image

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(input_path, tempfile = nil) ⇒ Image

Instance Methods




45
46
47
48
49
50
51
# File 'lib/mini_magick.rb', line 45

def initialize(input_path, tempfile=nil)
  @path = input_path
  @tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected.

  # Ensure that the file is an image
  run_command("identify", @path)
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)



129
130
131
132
133
# File 'lib/mini_magick.rb', line 129

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.



17
18
19
# File 'lib/mini_magick.rb', line 17

def output
  @output
end

#pathObject (readonly)

Returns the value of attribute path.



15
16
17
# File 'lib/mini_magick.rb', line 15

def path
  @path
end

#tempfileObject (readonly)

Returns the value of attribute tempfile.



16
17
18
# File 'lib/mini_magick.rb', line 16

def tempfile
  @tempfile
end

Class Method Details

.from_blob(blob, ext = nil) ⇒ Object



22
23
24
25
26
27
28
29
30
31
32
# File 'lib/mini_magick.rb', line 22

def from_blob(blob, ext = nil)
  begin
    tempfile = Tempfile.new(['mini_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



35
36
37
38
39
# File 'lib/mini_magick.rb', line 35

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



78
79
80
# File 'lib/mini_magick.rb', line 78

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

#[](value) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/mini_magick.rb', line 54

def [](value)
  # Why do I go to the trouble of putting in newlines? Because otherwise animated gifs screw everything up
  case value.to_s
  when "format"
    run_command("identify", "-format", format_option("%m"), @path).split("\n")[0]
  when "height"
    run_command("identify", "-format", format_option("%h"), @path).split("\n")[0].to_i
  when "width"
    run_command("identify", "-format", format_option("%w"), @path).split("\n")[0].to_i
  when "dimensions"
    run_command("identify", "-format", format_option("%w %h"), @path).split("\n")[0].split.map{|v|v.to_i}
  when "size"
    File.size(@path) # Do this because calling identify -format "%b" on an animated gif fails!
  when "original_at"
    # Get the EXIF original capture as a Time object
    Time.local(*self["EXIF:DateTimeOriginal"].split(/:|\s+/)) rescue nil
  when /^EXIF\:/i
    run_command('identify', '-format', "\"%[#{value}]\"", @path).chop
  else
    run_command('identify', '-format', "\"#{value}\"", @path).split("\n")[0]
  end
end

#collapse!Object

Collapse images with sequences to the first frame (ie. animated gifs) and preserve quality



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

def collapse!
  run_command("mogrify", "-quality", "100", "#{path}[0]")
end

#combine_options(&block) ⇒ Object

You can use multiple commands together using this method



136
137
138
139
140
# File 'lib/mini_magick.rb', line 136

def combine_options(&block)
  c = CommandBuilder.new
  block.call c
  run_command("mogrify", *c.args << @path)
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.



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/mini_magick.rb', line 86

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



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

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

#run_command(command, *args) ⇒ Object



152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# File 'lib/mini_magick.rb', line 152

def run_command(command, *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

  command = "#{MiniMagick.processor} #{command} #{args.join(' ')}".strip
  $stderr.puts "=====> #{command}"
  
  output = `#{command} 2>&1`

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

#to_blobObject

Give you raw data back



119
120
121
122
123
124
125
# File 'lib/mini_magick.rb', line 119

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)


143
144
145
# File 'lib/mini_magick.rb', line 143

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



113
114
115
116
# File 'lib/mini_magick.rb', line 113

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