ウォーターマーク(透かし)を敷き詰めた画像を RMagick で作る方法です。
また、CarrierWave と組み合わせるサンプルも一緒に紹介します。
ウォーターマークとは
サンプル画像とかに良く被さっているアレです。
fotowa1 ロゴで作るとこんな感じになります。
透け透けなのでほとんど見えませんが、例えばこの画像と組み合わせるとこうなります。
これは今回の最終成果物でもあります。
RMagick の mosaic で敷き詰めた画像を作る
ウォーターマークを敷き詰める際に、合成処理を繰り返し行ってしまうと非常に時間がかかります。一回試してみましたが実用不可な遅さでした。
そこで、mosaic を使って最初にウォーターマークを敷き詰めた画像を作成し、それを対象となる画像に合成することにします。
こうすることで、かなり処理を高速化することができます。
また mosaic はその名の通り、画像を大量に敷き詰めてモザイクにしてくれる機能です。
image = Magick::Image.read("target.png").first
mark = Magick::Image.read("watermark.png").first
mark.background_color = "none" # 背景色が指定されていると合成後にアルファチャネル部分がその色になる
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
注意すべきポイントはウォーターマークの背景色です。
例えば先程のウォーターマークには元々 "white" が指定されています。
もし背景色が設定されているまま mosaic を作りウォーターマークを敷き詰めると、
このように背景色で塗りつぶされてしまいます。
CarrierWave で使う
CarrierWave では RMagick と組み合わせ、画像のリサイズなどが簡単に行なえます。
例えば、process resize_to_fit: [2000, 1000]
などが利用可能です。
process
ではオリジナルメソッドも使えるので、それを定義し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
これで保存時にウォーターマークを敷き詰めたものも一緒に保存されるようになりました!
参考
- Module: CarrierWave::RMagick — Documentation for carrierwave (0.11.2)
- Ruby で複数枚の画像を一枚にタイル状にまとめた画像をつくるよ - RMagick の mosaic 使います - ヽ(゚ー゚ヽ)(ノ゚ー゚)ノわぁい
-
2016年1月からアーキテクト / リードエンジニアとして担当している Web サービス。 ↩