Class: MiniMagick::Image
- Inherits:
-
Object
- Object
- MiniMagick::Image
- Defined in:
- lib/mini_magick.rb
Instance Attribute Summary collapse
-
#path ⇒ String
readonly
The location of the current working file.
Class Method Summary collapse
-
.create(ext = nil) {|IOStream| ... } ⇒ Image
Used to create a new Image object data-copy.
-
.from_blob(blob, ext = nil) ⇒ Object
deprecated
Deprecated.
Please use Image.read instead!
-
.from_file(file, ext = nil) ⇒ Object
deprecated
Deprecated.
Please use MiniMagick::Image.open(file_or_url) now
-
.open(file_or_url, ext = File.extname(file_or_url)) ⇒ Image
Opens a specific image file either on the local file system or at a URI.
-
.read(stream, ext = nil) ⇒ Image
This is the primary loading method used by all of the other class methods.
Instance Method Summary collapse
-
#<<(*args) ⇒ String
Sends raw commands to imagemagick’s ‘mogrify` command.
-
#[](value) ⇒ String, ...
A rather low-level way to interact with the “identify” command.
-
#collapse! ⇒ Object
Collapse images with sequences to the first frame (ie. animated gifs) and preserve quality.
-
#combine_options {|command| ... } ⇒ Object
You can use multiple commands together using this method.
- #composite(other_image, output_extension = 'jpg', &block) ⇒ Object
- #destroy! ⇒ Object
- #escaped_path ⇒ Object
-
#format(format, page = 0) ⇒ nil
This is used to change the format of the image.
-
#format_option(format) ⇒ Object
Outputs a carriage-return delimited format string for Unix and Windows.
-
#initialize(input_path, tempfile = nil) ⇒ Image
constructor
Create a new MiniMagick::Image object.
-
#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).
- #run(command_builder) ⇒ Object
- #run_command(command, *args) ⇒ Object
-
#to_blob ⇒ String
Gives you raw image data back.
-
#valid? ⇒ Boolean
Checks to make sure that MiniMagick can read the file and understand it.
-
#windows? ⇒ Boolean
Check to see if we are running on win32 – we need to escape things differently.
-
#write(output_to) ⇒ IOStream, Boolean
Writes the temporary file out to either a file location (by passing in a String) or by passing in a Stream that you can #write(chunk) to repeatedly.
Constructor Details
#initialize(input_path, tempfile = nil) ⇒ Image
Allow this to accept a block that can pass off to Image#combine_options
Create a new MiniMagick::Image object
DANGER: The file location passed in here is the *working copy*. That is, it gets modified. you can either copy it yourself or use the MiniMagick::Image.open(path) method which creates a temporary file for you and protects your original!
129 130 131 132 |
# File 'lib/mini_magick.rb', line 129 def initialize(input_path, tempfile = nil) @path = input_path @tempfile = tempfile # ensures that the tempfile will stick around until this image is garbage collected. 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)
277 278 279 280 281 |
# File 'lib/mini_magick.rb', line 277 def method_missing(symbol, *args) do |c| c.method_missing(symbol, *args) end end |
Instance Attribute Details
#path ⇒ String (readonly)
Returns The location of the current working file.
31 32 33 |
# File 'lib/mini_magick.rb', line 31 def path @path end |
Class Method Details
.create(ext = nil) {|IOStream| ... } ⇒ Image
Used to create a new Image object data-copy. Not used to “paint” or that kind of thing.
Takes an extension in a block and can be used to build a new Image object. Used by both #open and #read to create a new object! Ensures we have a good tempfile!
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/mini_magick.rb', line 102 def create(ext = nil, &block) begin tempfile = Tempfile.new(['mini_magick', ext.to_s]) tempfile.binmode block.call(tempfile) tempfile.close image = self.new(tempfile.path, tempfile) if !image.valid? raise MiniMagick::Invalid end return image ensure tempfile.close if tempfile end end |
.from_blob(blob, ext = nil) ⇒ Object
Please use Image.read instead!
60 61 62 63 |
# File 'lib/mini_magick.rb', line 60 def from_blob(blob, ext = nil) warn "Warning: MiniMagick::Image.from_blob method is deprecated. Instead, please use Image.read" create(ext) { |f| f.write(blob) } end |
.from_file(file, ext = nil) ⇒ Object
Please use MiniMagick::Image.open(file_or_url) now
89 90 91 92 |
# File 'lib/mini_magick.rb', line 89 def from_file(file, ext = nil) warn "Warning: MiniMagick::Image.from_file is now deprecated. Please use Image.open" open(file, ext) end |
.open(file_or_url, ext = File.extname(file_or_url)) ⇒ Image
Opens a specific image file either on the local file system or at a URI.
Use this if you don’t want to overwrite the image file.
Extension is either guessed from the path or you can specify it as a second parameter.
If you pass in what looks like a URL, we require ‘open-uri’ before opening it.
76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/mini_magick.rb', line 76 def open(file_or_url, ext = File.extname(file_or_url)) file_or_url = file_or_url.to_s # Force it to be a String... hell or highwater if file_or_url.include?("://") require 'open-uri' self.read(Kernel::open(file_or_url), ext) else File.open(file_or_url, "rb") do |f| self.read(f, ext) end end end |
.read(stream, ext = nil) ⇒ Image
This is the primary loading method used by all of the other class methods.
Use this to pass in a stream object. Must respond to Object#read(size) or be a binary string object (BLOBBBB)
As a change from the old API, please try and use IOStream objects. They are much, much better and more efficient!
Probably easier to use the #open method if you want to open a file or a URL.
47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/mini_magick.rb', line 47 def read(stream, ext = nil) if stream.is_a?(String) stream = StringIO.new(stream) end create(ext) do |f| while chunk = stream.read(8192) f.write(chunk) end end end |
Instance Method Details
#<<(*args) ⇒ String
Sends raw commands to imagemagick’s ‘mogrify` command. The image path is automatically appended to the command.
Remember, we are always acting on this instance of the Image when messing with this.
200 201 202 |
# File 'lib/mini_magick.rb', line 200 def <<(*args) run_command("mogrify", *args << escaped_path) end |
#[](value) ⇒ String, ...
A rather low-level way to interact with the “identify” command. No nice API here, just the crazy stuff you find in ImageMagick. See the examples listed!
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/mini_magick.rb', line 167 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"), escaped_path).split("\n")[0] when "height" run_command("identify", "-format", format_option("%h"), escaped_path).split("\n")[0].to_i when "width" run_command("identify", "-format", format_option("%w"), escaped_path).split("\n")[0].to_i when "dimensions" run_command("identify", "-format", format_option("%w %h"), escaped_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 result = run_command('identify', '-format', "\"%[#{value}]\"", escaped_path).chop if result.include?(",") read_character_data(result) else result end else run_command('identify', '-format', "\"#{value}\"", escaped_path).split("\n")[0] end end |
#collapse! ⇒ Object
Collapse images with sequences to the first frame (ie. animated gifs) and preserve quality
240 241 242 |
# File 'lib/mini_magick.rb', line 240 def collapse! run_command("mogrify", "-quality", "100", "#{path}[0]") end |
#combine_options {|command| ... } ⇒ Object
You can use multiple commands together using this method. Very easy to use!
293 294 295 296 297 298 |
# File 'lib/mini_magick.rb', line 293 def (&block) c = CommandBuilder.new('mogrify') block.call(c) c << @path run(c) end |
#composite(other_image, output_extension = 'jpg', &block) ⇒ Object
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 |
# File 'lib/mini_magick.rb', line 305 def composite(other_image, output_extension = 'jpg', &block) begin second_tempfile = Tempfile.new(output_extension) second_tempfile.binmode ensure second_tempfile.close end command = CommandBuilder.new("composite") block.call(command) if block command.push(other_image.path) command.push(self.path) command.push(second_tempfile.path) run(command) return Image.new(second_tempfile.path, second_tempfile) end |
#destroy! ⇒ Object
359 360 361 362 363 |
# File 'lib/mini_magick.rb', line 359 def destroy! return if @tempfile.nil? File.unlink(@tempfile.path) @tempfile = nil end |
#escaped_path ⇒ Object
134 135 136 |
# File 'lib/mini_magick.rb', line 134 def escaped_path Pathname.new(@path).to_s.gsub(" ", "\\ ") end |
#format(format, page = 0) ⇒ nil
This is used to change the format of the image. That is, from “tiff to jpg” or something like that. Once you run it, the instance is pointing to a new file with a new extension!
DANGER: This renames the file that the instance is pointing to. So, if you manually opened the file with Image.new(file_path)… then that file is DELETED! If you used Image.open(file) then you are ok. The original file will still be there. But, any changes to it might not be…
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.
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 |
# File 'lib/mini_magick.rb', line 218 def format(format, page = 0) run_command("mogrify", "-format", format, @path) old_path = @path.dup @path.sub!(/(\.\w*)?$/, ".#{format}") File.delete(old_path) if old_path != @path unless File.exists?(@path) begin FileUtils.copy_file(@path.sub(".#{format}", "-#{page}.#{format}"), @path) rescue => ex raise MiniMagick::Error, "Unable to format to #{format}; #{ex}" 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
324 325 326 |
# File 'lib/mini_magick.rb', line 324 def format_option(format) windows? ? "\"#{format}\\n\"" : "\"#{format}\\\\n\"" end |
#run(command_builder) ⇒ Object
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 |
# File 'lib/mini_magick.rb', line 337 def run(command_builder) command = command_builder.command sub = Subexec.run(command, :timeout => MiniMagick.timeout) if sub.exitstatus != 0 # Clean up after ourselves in case of an error destroy! # Raise the appropriate error if sub.output =~ /no decode delegate/i || sub.output =~ /did not return an image/i raise Invalid, sub.output else # TODO: should we do something different if the command times out ...? # its definitely better for logging.. otherwise we dont really know raise Error, "Command (#{command.inspect.gsub("\\", "")}) failed: #{{:status_code => sub.exitstatus, :output => sub.output}.inspect}" end else sub.output end end |
#run_command(command, *args) ⇒ Object
328 329 330 331 332 333 334 335 |
# File 'lib/mini_magick.rb', line 328 def run_command(command, *args) # -ping "efficiently determine image characteristics." if command == 'identify' args.unshift '-ping' end run(CommandBuilder.new(command, *args)) end |
#to_blob ⇒ String
Gives you raw image data back
267 268 269 270 271 272 273 |
# File 'lib/mini_magick.rb', line 267 def to_blob f = File.new @path f.binmode f.read ensure f.close if f end |
#valid? ⇒ Boolean
Checks to make sure that MiniMagick can read the file and understand it.
This uses the ‘identify’ command line utility to check the file. If you are having issues with this, then please work directly with the ‘identify’ command and see if you can figure out what the issue is.
145 146 147 148 149 150 |
# File 'lib/mini_magick.rb', line 145 def valid? run_command("identify", @path) true rescue MiniMagick::Invalid false end |
#windows? ⇒ Boolean
Check to see if we are running on win32 – we need to escape things differently
301 302 303 |
# File 'lib/mini_magick.rb', line 301 def windows? !(RUBY_PLATFORM =~ /win32|mswin|mingw/).nil? end |
#write(output_to) ⇒ IOStream, Boolean
Writes the temporary file out to either a file location (by passing in a String) or by passing in a Stream that you can #write(chunk) to repeatedly
Writes the temporary image that we are using for processing to the output path
250 251 252 253 254 255 256 257 258 259 260 261 262 263 |
# File 'lib/mini_magick.rb', line 250 def write(output_to) if output_to.kind_of?(String) || !output_to.respond_to?(:write) FileUtils.copy_file @path, output_to run_command "identify", output_to # Verify that we have a good image else # stream File.open(@path, "rb") do |f| f.binmode while chunk = f.read(8192) output_to.write(chunk) end end output_to end end |