selflearn @ ウィキ

Watermarking Images With the shade Method

最終更新:

selflearn

- view
メンバー限定 登録/ログイン

Watermarking Images With the shade Method


開始日 2007年03月28日
最終更新日 2009年06月03日

はじめに

shadeメソッドを使って透かし画像(Watermarking Image)を作成する方法について記しています。

原著


「Watermarking Images With the shade Method」
http://rmagick.rubyforge.org/watermark/watermark.html

注意

  • もともと個人利用を目的として日本語化したために、けっこう意訳している部分があります。「意味分からないよ」とか「おかしいんじゃない?」とかいうのがあれば、オリジナルを参照するか、コメントで質問してください(がんばって調べます)。

用語

訳文に出てくる各語に対応する原文と意味を以下に記します。

訳語 原文 意味
元画像 source image 合成しようとしている画像。
合成先画像 destination image 元画像の下に重ねる画像。

更新履歴

  • 2007/3/28 作成開始


訳文


君は自分のWebサイトで使う「透かし(watermark)」の入った画像を作る方法を探しているのかい?君の写真を勝手に使われたくないんだって?写真のストックサイトであるiStockphotoでは、サンプル画像にサイト名を半透明の文字列で入れているね。この記事では、透明なエンボス加工されたテキストで透かしを入れる方法を紹介するよ。RMagickのshadeメソッドと、HardLightCompositeOpによるcompositeを使うんだ。

下の画像がこれから作ろうとしている画像の完成形だ。"Watermark by RMagick"というテキストが画像の上に浮き上がって見えるね。ちなみに「透かし」っていうのは、透明で画像を隠してしまわず、でも透かしのある部分を覗いてしまうと画像の意味がなくなってしまうもののことだ。実際の例として、君の写真に"Copyright © by John Smith"と埋め込むようなものなんだ。

imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
例のごとく、これはRMagickの初級コースなんかじゃない。RMagickの取り扱いに慣れていて、せめてRMagickで画像を読み書きできる知識を持っていることを期待しているからね。これまで書いてきた記事を読んでくれているなら、ここで紹介するメソッドは既に分かっていると思う。もしまだPart 1で書いたアルファコンポジットについての記事を読んでいないなら、ぜひとも読んでから戻ってきてほしい。
あぁ、もちろん待っていてあげるとも。

で、これがスクリプト全体だ。2ダース以上の行があるけれど、順々に説明していくから心配しないでくれ。
require 'RMagick'
 
if !ARGV[0]
    puts "Usage: watermark <path-to-image>"
    exit
end
 
image = Magick::Image.read(ARGV[0]).first
 
mark = Magick::Image.new(image.columns, image.rows)
 
gc = Magick::Draw.new
gc.gravity = Magick::CenterGravity
gc.pointsize = 32
gc.font_family = "Helvetica"
gc.font_weight = Magick::BoldWeight
gc.stroke = 'none'
gc.annotate(mark, 0, 0, 0, 0, "Watermark\nby\nRMagick")
 
mark = mark.shade(true, 310, 30)
 
image.composite!(mark, Magick::CenterGravity, Magick::HardLightCompositeOp)
 
out = ARGV[0].sub(/\./, "-wm.")
puts "Writing #{out}"
image.write(out)

透かしを入れる画像の読み込み(Read the image to be watermarked)

require 'RMagick'
 
if !ARGV[0]
    puts "Usage: watermark <path-to-image>"
    exit
end
 
image = Magick::Image.read(ARGV[0]).first
 
mark = Magick::Image.new(image.columns, image.rows)
このスクリプトでは、透かしを入れたい画像はコマンドラインのオプションで指定する。そして、(画像を読み込んだら)画像と同じサイズの白い背景画像を作成するんだ。厳密に言えば透かしを作る画像のサイズは読み込んだ画像と同じサイズである必要は無い。透かしが入るのに十分なサイズさえあれば、それでいいんだ。

透かしの記述(Draw the watermark)

gc = Magick::Draw.new
gc.gravity = Magick::CenterGravity
gc.pointsize = 32
gc.font_family = "Helvetica"
gc.font_weight = Magick::BoldWeight
gc.stroke = 'none'
gc.annotate(mark, 0, 0, 0, 0, "Watermark\nby\nRMagick")
Magick::Draw#annotateメソッドを使って、黒文字で白背景に文字を書いている。annotateメソッドを使う場合、annotateの属性を操作することでテキストプロパティを変更できるよ。ここではfont_weight,pointsize,font_familyプロパティで、Helveticaの太字32ptを指定している。たいてい、テキストはフチ取りに相当する線(stroke)と中の塗りつぶし部分(fill)で出来ているんだけど、今回はstrokeを"none"としてなくしている。塗りつぶし部分はデフォルト(黒)のままでいいからそのままだ。そしてgravityに関する属性で配置方法を決定する。CenterGravityなら画像の中央に配置してくれるから、それを使おう。
その結果が以下の画像だ。下の画像の周りにはボーダーラインがあるけれど*1、実際にはないからね。

imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。

テキストに影を付ける(Shade the text)

今のところ、文字はシンプルにフラットで黒色のままだ。でも、僕らは文字列を浮き上がらせ、強い光に照らされたようにしたい。こんなときはshadeメソッドの出番だ。RMagickのドキュメントを見てみると、shadeメソッドは「離れた光源がイメージを照らすことで、3次元的なエフェクトを与える」とある。ピッタリだね。
shadeメソッドには3つのパラメータを渡すよ。「陰影(shading)」と「光源の方位(azimuth)」と「光源の高さ(elevation)」だ。

shading引数にはtrueかfalseかのどちらかを渡す。trueを渡すと、影は各ピクセルの輝度情報のみによってつけられる。つまり結果として灰色の影が得られる。そう聞くとfalseの方が役立ちそうな気がするんだけど、実のところ僕もfalseの役割がよく分かっていないんだ。だからいつもtrueを渡しているよ。

2番目の引数azimuthでは、光源がどの方向に存在しているかを度単位(degree)で設定するんだ。0は9時の方向、つまり西だ。値が大きくなるにつれて反時計回りに光源が移動していくよ。90°は6時の方向(南)、180°は3時(東)、そして270°は正午(北)を意味する。

3番目の引数elevationは、画像平面に対する光源の角度として使用する。ここでの平面とは、画像がなす平面を表していて、文字のみを表すのではないからね。つまり、文字以外の背景にあたる部分も光源の影響を受けるというわけだ。
以下のelevationを表す図を見て理解してほしい。

imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
azimuthとelevationがどう作用するかを理解してもらうには・・・そうだ、この2つのパラメータを色々と変えてみたときの効果を画像にして見せればいいんだ。
さっそく作った下の図を説明しよう。ペアになっている数字はそれぞれ{azimuth, elevation}を表している。縦軸が同じazimuthで、横軸は同じelevationだ。
これを「Shade examiner」とでも呼ぼうかな。

imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
さて、その画像をそのまま見せようかと思ったけれど、640KBもあったんだ。これじゃあ細い回線を使っている人には向かないね。と言うわけで、圧縮画像(GIF形式)で書き出すようにしたよ。以下がそのソースだ。:
#!/usr/bin/env ruby
require 'RMagick'
 
mark = Magick::Image.new(125, 55)
 
ilist = Magick::ImageList.new
 
gc = Magick::Draw.new
gc.gravity = Magick::CenterGravity
gc.pointsize = 32
gc.font_family = "Times"
gc.font_weight = Magick::BoldWeight
gc.stroke = 'none'
 
0.step(360, 10) do |azimuth|
    0.step(180, 15) do |elev|
        frame = mark.copy
        gc.annotate(frame, 0, 0, 0, 0, "#{azimuth}, #{elev}")
        ilist << frame.shade(true, azimuth, elev)
        puts "Adding #{azimuth}, #{elev}"
    end
end
puts "Montaging..."
montage = ilist.montage do
    self.geometry = "125x55+0+0"
    self.tile = "13x36"
end
 
montage.write('shade_examiner.gif')

Tim - Feb 18, 2006


参考サイト(訳者による追加)




-

タグ:

Ruby RMagick
ウィキ募集バナー
注釈

*1 訳注:すみません、@Wikiでボーダーを指定する方法が分からなかったので、ここでは境界線は分からなくなっています。