Make Images Watermarked with RMagick (+ CarrierWave)
Summary
This post explains how to cover images with an array of a watermark.
Plus, I show an example how to use it with CarrierWave.
What is Watermark?
Watermark is an image which often covers sample images.
I made a sample of fotowa*1 logo:
You almost can't see it as it's really transparent. Let's say combine it with this picture, the image would be like this:
This is also the final product of this post.
Make an array of a watermark by mosaic of RMagick
It takes a lot of time to combine images multiply when you make images covered with an array of a watermark. I've tried it once, but it didn't work in realistic time.
So, make an array of a watermark at first and combine it with target images. Then, it really speeds up the process.
mosaic is, as the name shows, a feature which makes mosaic by arraying a lot of images.
image = Magick::Image.read("target.png").first mark = Magick::Image.read("watermark.png").first mark.background_color = "none" # If background color is specified, alpha channel becomes that color after combining images tile = Magick::ImageList.new page = Magick::Rectangle.new(0, 0, 0, 0) # Array watermarks to make it appropriate size (image.columns / mark.columns.to_f).ceil.times do |x| (image.rows / mark.rows.to_f).ceil.times do |y| tile << mark.dup page.x = x * tile.columns page.y = y * tile.rows tile.page = page end end
One point is the background color of a watermark. For example, the background color of the watermark I already showed is "white".
If you use a watermark whose background color is specified, images will be covered with the background color like this:
Use it with CarrierWave
You can easily manipulate images with CarrierWave and RMagick, like process resize_to_fit: [2000, 1000]
.
As it's okay to use any methods you define for process
, so define a method and use it in version
:
class ImageUploader < CarrierWave::Uploader::Base include CarrierWave::RMagick version :watermarked do process :watermark end def watermark mark = Magick::Image.read(Rails.root.join("lib", "assets", "watermark.png")).first mark.background_color = "none" manipulate! do |image| tile = Magick::ImageList.new page = Magick::Rectangle.new(0, 0, 0, 0) (image.columns / mark.columns.to_f).ceil.times do |x| (image.rows / mark.rows.to_f).ceil.times do |y| tile << mark.dup page.x = x * tile.columns page.y = y * tile.rows tile.page = page end end image.composite(tile.mosaic, 0, 0, Magick::OverCompositeOp) end end end
Finally, this uploader makes and stores watermarked images on uploading images!
References
- Module: CarrierWave::RMagick — Documentation for carrierwave (0.11.2)
- Ruby で複数枚の画像を一枚にタイル状にまとめた画像をつくるよ - RMagick の mosaic 使います - ヽ(゚ー゚ヽ)(ノ゚ー゚)ノわぁい
The original post was published on Jul. 8, 2016, by me in Japanese.
*1:Web service that I'm involved in as Software Architect / Lead Software Engineer