Processing
Changing data in some way, e.g. resizing an image, comes under the banner of Processing.
You can register as many processors as you like.
Let's say we have a Dragonfly app
app = Dragonfly[:images]
and an image object (actually a Job object)...
image = app.fetch('some/uid')
...OR a Dragonfly model accessor...
image = @album.cover_image
We can process it using any processing methods that have been registered with the processor.
ImageMagickProcessor
The ImageMagickProcessor is registered by default by the ImageMagick configuration used by 'dragonfly/rails/images'.
If not already registered:
app.processor.register(Dragonfly::Processing::ImageMagickProcessor)
gives us these methods:
image.process(:thumb, '400x300#') # see below
image.process(:crop, :width => 40, :height => 50, :x => 20, :y => 30)
image.process(:crop, :width => 40, :height => 50, :gravity => 'ne')
image.process(:flip) # flips it vertically
image.process(:flop) # flips it horizontally
image.process(:greyscale, :depth => 128) # default depth 256
image.process(:resize, '40x40')
image.process(:resize_and_crop, :width => 40, :height=> 50, :gravity => 'ne')
image.process(:rotate, 45, :background_colour => 'transparent') # default bg black
The method thumb
takes a geometry string and calls resize
, resize_and_crop
or crop
accordingly.
image.process(:thumb, '400x300') # calls resize
Below are some examples of geometry strings:
'400x300' # resize, maintain aspect ratio
'400x300!' # force resize, don't maintain aspect ratio
'400x' # resize width, maintain aspect ratio
'x300' # resize height, maintain aspect ratio
'400x300>' # resize only if the image is larger than this
'400x300<' # resize only if the image is smaller than this
'50x50%' # resize width and height to 50%
'400x300^' # resize width, height to minimum 400,300, maintain aspect ratio
'2000@' # resize so max area in pixels is 2000
'400x300#' # resize, crop if necessary to maintain aspect ratio (centre gravity)
'400x300#ne' # as above, north-east gravity
'400x300se' # crop, with south-east gravity
'400x300+50+100' # crop from the point 50,100 with width, height 400,300
RMagickProcessor
The RMagickProcessor uses the RMagick library and provides the methods
thumb
, crop
, flip
, flop
, greyscale
, resize
, resize_and_crop
and rotate
like the ImageMagickProcessor above.
You can tell it not to use the file system when registering it
app.processor.register(Dragonfly::Processing::RMagickProcessor){|p| p.use_filesystem = false }
Lazy evaluation
new_image = image.process(:some_method)
doesn't actually do anything until you call something on the returned Job object, like url
, data
, etc.
Bang method
image.process!(:some_method)
modifies the image object itself, rather than returning a new object.
Custom Processors
To register a single custom processor:
app.processor.add :watermark do |temp_object, *args|
# use temp_object.data, temp_object.path, temp_object.file, etc.
SomeLibrary.add_watermark(temp_object.data, 'some/watermark/file.png')
# return a String, File or Tempfile
end
new_image = image.process(:watermark)
You can create a class like the RMagick one above, in which case all public methods will be counted as processing methods. Each method takes the temp_object as its argument, plus any other args.
class MyProcessor
def coolify(temp_object, opts={})
SomeLib.coolify(temp_object.data, opts)
end
def uglify(temp_object, ugliness)
`uglify -i #{temp_object.path} -u #{ugliness}`
end
private
def my_helper_method
# do stuff
end
end
app.processor.register(MyProcessor)
new_image = image.coolify(:some => :args)
new_image = image.uglify(:loads)