Help us understand the problem. What is going on with this article?

RMagick (+ CarrierWave) でウォーターマーク(透かし)付きの画像を作る

More than 3 years have passed since last update.

ウォーターマーク(透かし)を敷き詰めた画像を RMagick で作る方法です。
また、CarrierWave と組み合わせるサンプルも一緒に紹介します。

ウォーターマークとは

サンプル画像とかに良く被さっているアレです。
fotowa1 ロゴで作るとこんな感じになります。

watermark.png

透け透けなのでほとんど見えませんが、例えばこの画像と組み合わせるとこうなります。

watermarked.jpg

これは今回の最終成果物でもあります。

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 を作りウォーターマークを敷き詰めると、

watermarked_1.jpg

このように背景色で塗りつぶされてしまいます。

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

これで保存時にウォーターマークを敷き詰めたものも一緒に保存されるようになりました!

参考


  1. 2016年1月からアーキテクト / リードエンジニアとして担当している Web サービス。 

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした