ImageMagickを使ってコマンドラインからCAPTCHAを作ってみる | A Day In The Boy's Life

A Day In The Boy's Life

とあるエンジニアのとある1日のつぶやき。

ImageMagick は、コマンドライン上から様々な画像処理が行え、JavaやC++やPerl、PHPとこれまた多くのプログラムからもAPIを通して利用することができるソフトウェアです。

Unix/Linuxだけでなく、MacOSやWindows版も用意されています。

 

WindowsやMacOSであれば、多機能な画像処理ソフトがあったりもしますが、画像フォーマットを変更したり、リサイズをしたりと単純な作業を大量に行いたいという場合は、ImageMagickのようなコマンドラインから操作した方が便利かもしれません。

 

 

今回は、Linux環境(CentOS5.5)上でコマンドラインからの操作を中心に書いています。

 

そして、Webサービス上でよく使われるCAPTCHA(数字や文字の画像を表示して入力させるあれ)を作ってみます。

かなりオプションが多い ので、マニュアルもあわせて参照してみてください。

 

ImageMagickがインストールされていない場合は、yumコマンドから

 

 

# yum install -y ImageMagick.i386

 

 

とすることでインストールできるかもしれません。

 

 

 

ImageMagickからCAPTCHAを作ってみる

 

 

 

簡単な数字を並べ多少加工した画像を、コマンドラインから生成して出力してみます。

 

 

$ convert -size 200x50 xc:white -font /usr/share/fonts/ja/TrueType/kochi-gothic-subst.ttf -fill gray -pointsize 32 -gravity center -draw 'text 0,0 "1 4 6 0 7"' -swirl 50 -rotate 10 -fill blue -draw 'line 5,35 95,5' -fill red -draw 'line 20,55 180,45' image.gif

 

 

- 作った画像

 

A Day In The Boy's Life-CAPTCHA

オプションがいっぱい付いているので、以下その解説。

ちなみに、ImageMagickでは指定したオプションを順番に処理していくため、順番を入れ替えた場合には異なる画像ができあがります

 

□ 新規に画像を作成するオプション

 


まず、新規に画像を作る場合は、下記のようなオプションを指定します。

 

# convert -size 100x100 xc:white image.gif

 

 

上記で、横100px縦100pxのサイズで、背景が白のimage.gifファイルを作成しています。

 

 

 

□ 文字のフォントを指定するオプション

 

 

 

次のfontオプション ではその後のdrawオプションで書く文字のフォントを指定しています。

 

これは、環境内にインストールされているフォントを適当に指定しましょう。

もし、使っているLinux環境にフォントがインストールされていない場合は、フリーで配られているフォントをダウンロードして、サーバー上の/usr/share/fonts/以下の適当なディレクトリにコピーするか、yumで配られているフォントパッケージをインストールすれば使えるようになると思います。

 

# yum install fonts-japanese

 

 

- FreeSerifフォントで描いた場合

 

A Day In The Boy's Life-CAPTCHA-2

 

□ 文字の色と大きさを指定するオプション

 

 

次の、fillオプションpointsizeオプション はそれぞれ描く文字や線の色と文字の大きさを指定します。

 

上記の場合は、グレーの文字で文字サイズが32ポイントで書くように指定してます。

色はカラー名を指定 することもできますし、頭に#を付けた16進数で指定することも可能です。

(CSS内で色を指定する場合と同様ですね)

 

 

□ 文字のセンター寄せを指定するオプション

 

 

 

gravityオプション にcenterを指定することで文字を画像の真ん中に寄せることができます。

 

ただし、CAPTCHAを作るという意味では、文字の表示位置が固定になるのは、CAPTCHA解析をしやすくなることにもなるので、弱点にもなってしまいます。

文字の出力位置を不定にしたい場合は、次のdrawオプション内で、文字を書く位置を毎回ずらして出力した方が良いかもしれません。

 

 

□ 文字や線を書くオプション

 

 


次に(そして後半に線を書くために指定している)drawオプション では、キャンパス内に文字や線、円やその他の画像を描くことを指定することができます。

最初のdrawオプションでは、引数内にtextを指定することでCAPTCHA用の数字を描いています。

数字だけでは弱いという場合は、この中に英字も含めて出力すればより強固なものになるでしょう。

また、最初の数字にてどこから文字を描くか(X軸とY軸の座標)を指定できます。

これも、毎回キャンバスに収まる範囲で出力位置を変えることでより強固なCAPTCHAを作ることができるでしょう。

 

最後に指定している線(drawオプションの引数にlineを指定)は、CAPTCHAに描いた数字を人間にはわかるがコンピュータにはわかりづらくするために、入れているものです。

 

最初の線は青色で、(5, 35)の位置から(95, 5)の座標まで線を引っ張ってます。

同様に、赤色の線を(20, 55)の位置から(180, 55)の位置まで引っ張っています。

色や引っ張る線の数、そして線の引き方を変えればCAPTCHAを解析されにくくなるかもしれません。

あまりやりすぎると視認性が悪くなって、人も読めなくなりますけどね・・・。

 

- 線の変わりに円を出力してみた例

 

A Day In The Boy's Life-CAPTCHA-3

 

上記を出力した際のオプションは下記。

 

 

$ convert -size 200x50 xc:white -font /usr/share/fonts/ja/TrueType/kochi-gothic-subst.ttf -fill gray -pointsize 32 -gravity center -draw 'text 0,0 "1 4 6 0 7"' -swirl 50 -rotate 10 -fill none -stroke blue  -draw 'circle 95,50 75,30' -fill none -stroke red -draw 'circle 25,20 10,10' image.gif

 

 

fillオプションにnoneを指定することで円の中を透明にし、淵だけの円を描くことができます。

 

そして、淵の色はstrokeオプション で指定します。

 

 

□ 画像を渦状に加工するオプション

 

 

 

数字をよく見ると少しうねうねしていますが、人が見てわかる範囲のレベルで数字を加工して解析できにくくしています。

 

これは、swirlオプション によるもので、これを指定すると画像を渦状に加工することができます。

渦状に加工するレベルはその引数で指定できますので、視認性が保たれるレベルで出力する文字を加工してみればよいでしょう。

 

 

□ 画像を回転させるオプション

 

 

 

平坦に文字を書いてしまうと、コンピュータからも読みやすいものになってしまいますので、rotateオプション で画像を回転させて、見破られにくいものにしています。

 

これも、キャンバス内に収まる範囲で回転率を毎回違うものに指定すればより強固なCAPTCHAができるかもしれません。

 

 

まとめ

 

 

 

コマンドラインだけでできると書きつつも、オプションに指定する数値やCAPCHAの中身の文字は毎回変えないと意味がありませんので、やはりプログラム内からImageMagickを呼び出して画像を生成するというやり方の方が賢いかもしれません。

 

 

また、複数の画像を重ね合わせたり、文字を1文字ずつ異なる色で描いたりしてみたり、その他のオプションを使って画像をより複雑なものに加工することもできるので、自分なりのCAPTCHAを作ってみるのも楽しいでしょう。

 

何よりコマンドラインからも手軽に画像を生成することができますので、CAPTCHA以外にもImageMagickを応用する方法は多々あると思います。