lib/carrierwave/processing/rmagick.rb in carrierwave-0.6.2 vs lib/carrierwave/processing/rmagick.rb in carrierwave-0.7.0
- old
+ new
@@ -88,10 +88,14 @@
end
def resize_and_pad(width, height, background=:transparent, gravity=::Magick::CenterGravity)
process :resize_and_pad => [width, height, background, gravity]
end
+
+ def resize_to_geometry_string(geometry_string)
+ process :resize_to_geometry_string => [geometry_string]
+ end
end
##
# Changes the image encoding format to the given format
#
@@ -222,10 +226,32 @@
filled
end
end
##
+ # Resize the image per the provided geometry string.
+ #
+ # === Parameters
+ #
+ # [geometry_string (String)] the proportions in which to scale image
+ #
+ # === Yields
+ #
+ # [Magick::Image] additional manipulations to perform
+ #
+ def resize_to_geometry_string(geometry_string)
+ manipulate! do |img|
+ new_img = img.change_geometry(geometry_string) do |new_width, new_height|
+ img.resize(new_width, new_height)
+ end
+ destroy_image(img)
+ new_img = yield(new_img) if block_given?
+ new_img
+ end
+ end
+
+ ##
# Manipulate the image with RMagick. This method will load up an image
# and then pass each of its frames to the supplied block. It will then
# save the image to disk.
#
# === Gotcha
@@ -236,46 +262,95 @@
# most cases.
#
# === Yields
#
# [Magick::Image] manipulations to perform
+ # [Integer] Frame index if the image contains multiple frames
+ # [Hash] options, see below
#
+ # === Options
+ #
+ # The options argument to this method is also yielded as the third
+ # block argument.
+ #
+ # Currently, the following options are defined:
+ #
+ # ==== :write
+ # A hash of assignments to be evaluated in the block given to the RMagick write call.
+ #
+ # An example:
+ #
+ # manipulate! do |img, index, options|
+ # options[:write] = {
+ # :quality => 50,
+ # :depth => 8
+ # }
+ # img
+ # end
+ #
+ # This will translate to the following RMagick::Image#write call:
+ #
+ # image.write do |img|
+ # self.quality = 50
+ # self.depth = 8
+ # end
+ #
+ # ==== :read
+ # A hash of assignments to be given to the RMagick read call.
+ #
+ # The options available are identical to those for write, but are passed in directly, like this:
+ #
+ # manipulate! :read => { :density => 300 }
+ #
+ # ==== :format
+ # Specify the output format. If unset, the filename extension is used to determine the format.
+ #
# === Raises
#
# [CarrierWave::ProcessingError] if manipulation failed.
#
def manipulate!(options={}, &block)
cache_stored_file! if !cached?
- image = ::Magick::Image.read(current_path)
+ read_block = create_info_block(options[:read])
+ image = ::Magick::Image.read(current_path, &read_block)
+
frames = if image.size > 1
list = ::Magick::ImageList.new
image.each_with_index do |frame, index|
processed_frame = if block_given?
- yield *[frame, index].take(block.arity)
+ yield *[frame, index, options].take(block.arity)
else
frame
end
list << processed_frame if processed_frame
end
block_given? ? list : list.append(true)
else
frame = image.first
- frame = yield( *[frame, 0].take(block.arity) ) if block_given?
+ frame = yield( *[frame, 0, options].take(block.arity) ) if block_given?
frame
end
+ write_block = create_info_block(options[:write])
if options[:format]
- frames.write("#{options[:format]}:#{current_path}")
+ frames.write("#{options[:format]}:#{current_path}", &write_block)
else
- frames.write(current_path)
+ frames.write(current_path, &write_block)
end
destroy_image(frames)
rescue ::Magick::ImageMagickError => e
raise CarrierWave::ProcessingError, I18n.translate(:"errors.messages.rmagick_processing_error", :e => e)
end
private
+
+ def create_info_block(options)
+ return nil unless options
+ assignments = options.map { |k, v| "self.#{k} = #{v}" }
+ code = "lambda { |img| " + assignments.join(";") + "}"
+ eval code
+ end
def destroy_image(image)
image.destroy! if image.respond_to?(:destroy!)
end