HOWTO: Watermarking Images with ImageMagick and attachment_fu
Thursday, January 14th, 2010While working on a project for the State Hermitage Museum last year, I had to implement some image watermarking. The basic requirement was that for a certain type of uploaded image, its largest thumbnail should have the museum’s logo tiled across it. I was using attachment_fu to handle the image upload, and ImageMagick/RMagick to process the thumbnails.
After some cursory Googling, I found the ImageMagick Annotating guide, which had this sample watermark command:
$ convert overlay.png -fill grey50 -colorize 40 miff:- |\ composite -dissolve 15 -tile - original.jpg watermarked_image.jpg
The dissection of the command:
overlay.png: The source image to overlay
-fill grey50 -colorize 40: Alter the colors of the watermark file
composite: command to overlay the watermark
-dissolve 15 -tile: “dissolve” the overlay at 15%, for good transparency, and tile (repeat) the watermark over the source image.
That’s simple enough, and with these source files:
and dearest Rufus:
$ convert overlay.png -fill grey50 -colorize 40 miff:- |\ composite -dissolve 15 -tile - rufus.jpg result-15.jpg
Produces:
convert overlay.png -fill grey50 -colorize 40 miff:- |\ composite -dissolve 50 -tile - rufus.jpg result-50.jpg
Unfortunately, RMagick’s watermark method doesn’t support tiling. To work around, I had to call the composite_tiled! method on a colorized image. This code is in my Thumbnail model, which includes attachment_fu:
class Thumbnail < ActiveRecord::Base has_attachment :content_type => :image, # some settings omitted :watermark_overlay => File.join(RAILS_ROOT, '/public/images/watermark-overlay-image.png'), :watermarkable_size => "1500>" after_attachment_saved do |record| if record.respond_to?(:parent_id) and record.parent_id.nil? # the original image, not the smaller thumbnails with_image record.full_filename do |img| img.composite_tiled!( Magick::ImageList.new(attachment_options[:watermark_overlay]).first.colorize(0.4, 0.4, 0.4, 'grey'), # process and colorize image Magick::SoftLightCompositeOp) img.write record.full_filename # save image end end end end
Now every Thumbnail record will automatically have a watermarked large image.



