All Google queries for watermarking an image with ActiveStorage currently point to this great, thorough result from 2018. ActiveStorage has changed a lot in the past three years, and change_options
is no longer the going syntax as of 2021.
It can be much simpler to generate primitive watermarks with ActiveStorage 6.1. The basic concept remains the same: you pass imagemagick command line options to the variant
method of your attachment. Given the wealth of options that imagemagick provides, it's a very flexible way to make a lot of possible things happen to an image.
Given a model called Feature
that includes a has_one_attached :screenshot
, this incantation will emboss the words "NoteApps.info" in the lower-right corner of an image.
image_processing
default (as of 6.1) processor, imagemagick
To process a watermark variant with the imagemagick
processor
It uses two key options: "text" and "gravity" from imagemagick.
So an image like this:
Has this variant generated (squint your eyes and look at the lower right corner):
image_processing
's ruby-vips
processorAnother watermarking exercise we needed to undertake was to add "gitclear.com" to the bottom of some images that would be dynamically generated by customers. We decided to use ruby-vips
for this since the gem is automatically installed with image_processing
and their documentation promises substantially faster processing than imagemagick. Inspired by the ruby-vips example provided here, we used this code to go from a watir screenshot to an ActiveStorage image with a watermark:
If you open test.png after running this, you'll discover a beauty like this:
Note the text in the lower-right corner. 💅
These options are best combined with the Rails' much appreciated new option to store which variants have been previously generated in the database, and reuse those instead of regenerating (+ reuploading) a new image on every call to the variant
method.
Since all this ActiveStorage variant business is relatively new as of mid-2021, work is still ongoing to ensure that variants can be preloaded to avoid an N+1 query situation when showing many images on a page. This PR looks set to offer new methods that can be utilized to eager-load an attachment and its variants. In the meantime, the following patch can be added to config/initializers
to allow the possibility of using variant records when they have been preloaded:
Of course, if you are looking to show the public version of these watermarked images, the path to ensuring the resource is eager-loaded won't be mistaken for simple:
The outer screenshot_attachment
is the name of the attachment added to Feature
. Variant records are recorded by blob, so we must look up both of those. The actual key used by the variant image is nestled even further down, in the variant_record
's own has_one_attached :image
association, which holds yet another blob 😅. It looks like the incoming PR doesn't simplify this possible variant lookup, which makes me wonder if there is supposed to be an easier way to load the public key used by rails_public_blob_url
. Feel free to drop a line in the comments if you discover a better way to ensure no N+1 looking up the public URL of a generated variant.