lib/mojo_magick.rb in mojo_magick-0.5.4 vs lib/mojo_magick.rb in mojo_magick-0.5.5
- old
+ new
@@ -1,188 +1,194 @@
-cwd = File::dirname(__FILE__)
-require 'open3'
-initializers_dir = File::expand_path(File::join(cwd, 'initializers'))
-Dir.glob(File::join(initializers_dir, '*.rb')).each { |f| require f }
-require File::join(cwd, 'mojo_magick/util/parser')
-require File::join(cwd, 'image_magick/resource_limits')
-require File::join(cwd, 'image_magick/fonts')
-require File::join(cwd, 'mojo_magick/opt_builder')
-require File::join(cwd, 'mojo_magick/font')
-require 'tempfile'
-
-
-# MojoMagick is a stateless set of module methods which present a convient interface
-# for accessing common tasks for ImageMagick command line library.
-#
-# MojoMagick is specifically designed to be efficient and simple and most importantly
-# to not leak any memory. For complex image operations, you will find MojoMagick limited.
-# You might consider the venerable MiniMagick or RMagick for your purposes if you care more
-# about ease of use rather than speed and memory management.
-
-# all commands raise "MojoMagick::MojoFailed" if command fails (ImageMagick determines command success status)
-
-# Two command-line builders, #convert and #mogrify, have been added to simplify
-# complex commands. Examples included below.
-#
-# Example #convert usage:
-#
-# MojoMagick::convert('source.jpg', 'dest.jpg') do |c|
-# c.crop '250x250+0+0'
-# c.repage!
-# c.strip
-# c.set 'comment', 'my favorite file'
-# end
-#
-# Equivalent to:
-#
-# MojoMagick::raw_command('convert', 'source.jpg -crop 250x250+0+0 +repage -strip -set comment "my favorite file" dest.jpg')
-#
-# Example #mogrify usage:
-#
-# MojoMagick::mogrify('image.jpg') {|i| i.shave '10x10'}
-#
-# Equivalent to:
-#
-# MojoMagick::raw_command('mogrify', '-shave 10x10 image.jpg')
-#
-# Example showing some additional options:
-#
-# MojoMagick::convert do |c|
-# c.file 'source.jpg'
-# c.blob my_binary_data
-# c.append
-# c.crop '256x256+0+0'
-# c.repage!
-# c.file 'output.jpg'
-# end
-#
-# Use .file to specify file names, .blob to create and include a tempfile. The
-# bang (!) can be appended to command names to use the '+' versions
-# instead of '-' versions.
-#
-module MojoMagick
-
- class MojoMagickException < StandardError; end
- class MojoError < MojoMagickException; end
- class MojoFailed < MojoMagickException; end
-
- # enable resource limiting functionality
- extend ImageMagick::ResourceLimits
- extend ImageMagick::Fonts
-
- def MojoMagick::windows?
- mem_fix = 1
- !(RUBY_PLATFORM =~ /win32/).nil?
- end
-
- def MojoMagick::raw_command(command, args, options = {})
- # this suppress error messages to the console
- # err_pipe = windows? ? "2>nul" : "2>/dev/null"
- out = outerr = status = nil
- begin
- execute = "#{command} #{get_limits_as_params} #{args}"
- out, outerr, status = Open3.capture3(execute)
- retval = out
- # guarantee that only MojoError exceptions are raised here
- rescue Exception => e
- raise MojoError, "#{e.class}: #{e.message}"
- end
- if !status.success?
- err_msg = options[:err_msg] || "MojoMagick command failed: #{command}."
- raise(MojoFailed, "#{err_msg} (Exit status: #{$?.exitstatus})\n Command: #{execute}\n Error: #{outerr}")
- end
- retval
- end
-
- def MojoMagick::shrink(source_file, dest_file, options)
- opts = options.dup
- opts.delete(:expand_only)
- MojoMagick::resize(source_file, dest_file, opts.merge(:shrink_only => true))
- end
-
- def MojoMagick::expand(source_file, dest_file, options)
- opts = options.dup
- opts.delete(:shrink_only)
- MojoMagick::resize(source_file, dest_file, opts.merge(:expand_only => true))
- end
-
- # resizes an image and returns the filename written to
- # options:
- # :width / :height => scale to these dimensions
- # :scale => pass scale options such as ">" to force shrink scaling only or "!" to force absolute width/height scaling (do not preserve aspect ratio)
- # :percent => scale image to this percentage (do not specify :width/:height in this case)
- def MojoMagick::resize(source_file, dest_file, options)
- retval = nil
- scale_options = []
- scale_options << ">" unless options[:shrink_only].nil?
- scale_options << "<" unless options[:expand_only].nil?
- scale_options << "!" unless options[:absolute_aspect].nil?
- scale_options << "^" unless options[:fill].nil?
- scale_options = scale_options.join
-
- extras = []
- if !options[:width].nil? && !options[:height].nil?
- geometry = "#{options[:width]}X#{options[:height]}"
- elsif !options[:percent].nil?
- geometry = "#{options[:percent]}%"
- else
- raise MojoMagickError, "Unknown options for method resize: #{options.inspect}"
- end
- if !options[:fill].nil? && !options[:crop].nil?
- extras << "-gravity Center"
- extras << "-extent #{geometry}"
- end
- retval = raw_command("convert", "\"#{source_file}\" -resize \"#{geometry}#{scale_options}\" #{extras.join(' ')} \"#{dest_file}\"")
- dest_file
- end
-
- def MojoMagick::available_fonts
- # returns width, height of image if available, nil if not
- Font.all
- end
-
- # returns an empty hash or a hash with :width and :height set (e.g. {:width => INT, :height => INT})
- # raises MojoFailed when results are indeterminate (width and height could not be determined)
- def MojoMagick::get_image_size(source_file)
- # returns width, height of image if available, nil if not
- retval = raw_command("identify", "-format \"w:%w h:%h\" \"#{source_file}\"")
- return {} if !retval
- width = retval.match(%r{w:([0-9]+) })
- width = width ? width[1].to_i : nil
- height = retval.match(%r{h:([0-9]+)})
- height = height ? height[1].to_i : nil
- raise(MojoFailed, "Indeterminate results in get_image_size: #{source_file}") if !height || !width
- {:width=>width, :height=>height}
- end
-
- def MojoMagick::convert(source = nil, dest = nil)
- opts = OptBuilder.new
- opts.file source if source
- yield opts
- opts.file dest if dest
- raw_command('convert', opts.to_s)
- end
-
- def MojoMagick::mogrify(dest = nil)
- opts = OptBuilder.new
- yield opts
- opts.file dest if dest
- raw_command('mogrify', opts.to_s)
- end
-
- def MojoMagick::tempfile(*opts)
- begin
- data = opts[0]
- rest = opts[1]
- ext = rest && rest[:format]
- file = Tempfile.new(["mojo", ext ? '.' + ext.to_s : ''])
- file.binmode
- file.write(data)
- file.path
- rescue Exception => ex
- raise
- ensure
- file.close
- end
- end
-
-end # MojoMagick
+cwd = File::dirname(__FILE__)
+require 'open3'
+initializers_dir = File::expand_path(File::join(cwd, 'initializers'))
+Dir.glob(File::join(initializers_dir, '*.rb')).each { |f| require f }
+require File::join(cwd, 'mojo_magick/util/parser')
+require File::join(cwd, 'mojo_magick/errors')
+require File::join(cwd, 'mojo_magick/command_status')
+require File::join(cwd, 'image_magick/resource_limits')
+require File::join(cwd, 'image_magick/fonts')
+require File::join(cwd, 'mojo_magick/opt_builder')
+require File::join(cwd, 'mojo_magick/font')
+require 'tempfile'
+
+
+# MojoMagick is a stateless set of module methods which present a convient interface
+# for accessing common tasks for ImageMagick command line library.
+#
+# MojoMagick is specifically designed to be efficient and simple and most importantly
+# to not leak any memory. For complex image operations, you will find MojoMagick limited.
+# You might consider the venerable MiniMagick or RMagick for your purposes if you care more
+# about ease of use rather than speed and memory management.
+
+# all commands raise "MojoMagick::MojoFailed" if command fails (ImageMagick determines command success status)
+
+# Two command-line builders, #convert and #mogrify, have been added to simplify
+# complex commands. Examples included below.
+#
+# Example #convert usage:
+#
+# MojoMagick::convert('source.jpg', 'dest.jpg') do |c|
+# c.crop '250x250+0+0'
+# c.repage!
+# c.strip
+# c.set 'comment', 'my favorite file'
+# end
+#
+# Equivalent to:
+#
+# MojoMagick::raw_command('convert', 'source.jpg -crop 250x250+0+0 +repage -strip -set comment "my favorite file" dest.jpg')
+#
+# Example #mogrify usage:
+#
+# MojoMagick::mogrify('image.jpg') {|i| i.shave '10x10'}
+#
+# Equivalent to:
+#
+# MojoMagick::raw_command('mogrify', '-shave 10x10 image.jpg')
+#
+# Example showing some additional options:
+#
+# MojoMagick::convert do |c|
+# c.file 'source.jpg'
+# c.blob my_binary_data
+# c.append
+# c.crop '256x256+0+0'
+# c.repage!
+# c.file 'output.jpg'
+# end
+#
+# Use .file to specify file names, .blob to create and include a tempfile. The
+# bang (!) can be appended to command names to use the '+' versions
+# instead of '-' versions.
+#
+module MojoMagick
+
+ # enable resource limiting functionality
+ extend ImageMagick::ResourceLimits
+ extend ImageMagick::Fonts
+
+ def MojoMagick::windows?
+ mem_fix = 1
+ !(RUBY_PLATFORM =~ /win32/).nil?
+ end
+
+ def MojoMagick::execute(command, args, options = {})
+ # this suppress error messages to the console
+ # err_pipe = windows? ? "2>nul" : "2>/dev/null"
+ begin
+ execute = "#{command} #{get_limits_as_params} #{args}"
+ out, outerr, status = Open3.capture3(execute)
+ CommandStatus.new execute, out, outerr, status
+ rescue Exception => e
+ raise MojoError, "#{e.class}: #{e.message}"
+ end
+ end
+
+ def MojoMagick::execute!(command, args, options = {})
+ # this suppress error messages to the console
+ # err_pipe = windows? ? "2>nul" : "2>/dev/null"
+ status = execute(command, args, options)
+ if !status.success?
+ err_msg = options[:err_msg] || "MojoMagick command failed: #{command}."
+ raise(MojoFailed, "#{err_msg} (Exit status: #{status.exit_code})\n Command: #{status.command}\n Error: #{status.error}")
+ end
+ status.return_value
+ end
+
+ def MojoMagick::raw_command(*args)
+ self.execute! *args
+ end
+
+ def MojoMagick::shrink(source_file, dest_file, options)
+ opts = options.dup
+ opts.delete(:expand_only)
+ MojoMagick::resize(source_file, dest_file, opts.merge(:shrink_only => true))
+ end
+
+ def MojoMagick::expand(source_file, dest_file, options)
+ opts = options.dup
+ opts.delete(:shrink_only)
+ MojoMagick::resize(source_file, dest_file, opts.merge(:expand_only => true))
+ end
+
+ # resizes an image and returns the filename written to
+ # options:
+ # :width / :height => scale to these dimensions
+ # :scale => pass scale options such as ">" to force shrink scaling only or "!" to force absolute width/height scaling (do not preserve aspect ratio)
+ # :percent => scale image to this percentage (do not specify :width/:height in this case)
+ def MojoMagick::resize(source_file, dest_file, options)
+ retval = nil
+ scale_options = []
+ scale_options << ">" unless options[:shrink_only].nil?
+ scale_options << "<" unless options[:expand_only].nil?
+ scale_options << "!" unless options[:absolute_aspect].nil?
+ scale_options << "^" unless options[:fill].nil?
+ scale_options = scale_options.join
+
+ extras = []
+ if !options[:width].nil? && !options[:height].nil?
+ geometry = "#{options[:width]}X#{options[:height]}"
+ elsif !options[:percent].nil?
+ geometry = "#{options[:percent]}%"
+ else
+ raise MojoMagickError, "Unknown options for method resize: #{options.inspect}"
+ end
+ if !options[:fill].nil? && !options[:crop].nil?
+ extras << "-gravity Center"
+ extras << "-extent #{geometry}"
+ end
+ retval = raw_command("convert", "\"#{source_file}\" -resize \"#{geometry}#{scale_options}\" #{extras.join(' ')} \"#{dest_file}\"")
+ dest_file
+ end
+
+ def MojoMagick::available_fonts
+ # returns width, height of image if available, nil if not
+ Font.all
+ end
+
+ # returns an empty hash or a hash with :width and :height set (e.g. {:width => INT, :height => INT})
+ # raises MojoFailed when results are indeterminate (width and height could not be determined)
+ def MojoMagick::get_image_size(source_file)
+ # returns width, height of image if available, nil if not
+ retval = raw_command("identify", "-format \"w:%w h:%h\" \"#{source_file}\"")
+ return {} if !retval
+ width = retval.match(%r{w:([0-9]+) })
+ width = width ? width[1].to_i : nil
+ height = retval.match(%r{h:([0-9]+)})
+ height = height ? height[1].to_i : nil
+ raise(MojoFailed, "Indeterminate results in get_image_size: #{source_file}") if !height || !width
+ {:width=>width, :height=>height}
+ end
+
+ def MojoMagick::convert(source = nil, dest = nil)
+ opts = OptBuilder.new
+ opts.file source if source
+ yield opts
+ opts.file dest if dest
+ raw_command('convert', opts.to_s)
+ end
+
+ def MojoMagick::mogrify(dest = nil)
+ opts = OptBuilder.new
+ yield opts
+ opts.file dest if dest
+ raw_command('mogrify', opts.to_s)
+ end
+
+ def MojoMagick::tempfile(*opts)
+ begin
+ data = opts[0]
+ rest = opts[1]
+ ext = rest && rest[:format]
+ file = Tempfile.new(["mojo", ext ? '.' + ext.to_s : ''])
+ file.binmode
+ file.write(data)
+ file.path
+ rescue Exception => ex
+ raise
+ ensure
+ file.close
+ end
+ end
+
+end # MojoMagick