JCaptchaで日本語

表示に使用されるテキストは「toddlist.properties」ファイルに保存されています。
まず単純に「toddlist_ja.properties」を作ってみます。
単語を「;」で区切って登録します。

words=あいうえお;かきくけこ;さしすせそ

※native2asciiを忘れずに
しかしこれでは、フォントが合わないため上手く表示されません。
単純に辞書ファイルを用意するだけではダメなようです。


Springで使用するためのサンプルを読み解くと、
最終的にImageCaptchaServieインタフェースを実装したクラスを組み立てるようです。
今回は「GenericManageableCaptchaService」を使用します。
ImageCaptchaServiceを組み立てるために、以下の二つのインタフェースを実装したクラスが必要となります。
()の中は今回使用するクラス。

  • CaptchaEngine(GenericCaptchaEngine)
  • ImageCaptchaFactory(GimpyFactory)


まず、GimpyFactoryから組み立てて行きます。
このコンストラクタの引数には「WordGenerator」「WordToImage」を渡す必要があります。
WordGeneratorはどのように文字を作るかを指定します。
WordToImageは作成した文字に対して変形等どうイメージにするかを指定します。


まず、WordGeneratorからです。
どの辞書を使用するかを指定するために、下記ようにしてWordGeneratorを作成します。
ここでは「mydictionary.properties」という名前の辞書ファイルを使用します。

FileDictionary dictionary = new FileDictionary("mydictionay");
WordGenerator wordgen = new CoposeDictionaryWordGenerator(dictionary);

次は、WordToImageです。
これが結構面倒です。
今回は「DeformedComposedWordToImage」を使用するのですが、
フォントの生成、背景の生成、文字の貼り付け方、背景の変形方法、文字の変形方法など指定する必要があります。


まずはフォントから。
今回は「FontGenerator」インタフェースを実装した「RandomFontGenerator」を使用します。
これは下記のように、コンストラクタに使用するフォントを渡します。

FontGenerator fontGenerator = new RandomFontGenerator(40,50,new Font[]{new Font("MS ゴシック",0,10),new Font("MS 明朝",0,10),new Font("MS Pゴシック",0,10),new Font("MS P明朝",0,10)});

次、背景。
「BackgroundGenerator」インタフェースを実装した「UniColorBackgroundGenerator」を使用します。
これは単色で背景を生成するクラスです。
引数に生成する幅・高さ・色を渡せます。色は指定しないと白になるようです。

BackgroundGenerator backgroundGenerator = new UniColorBackgroundGenerator(300,100);

次、文字の貼り付け方。
「TextPaster」インタフェースを実装した「RandomTextPaster」を使用します。
RandomTextPasterのコンストラクタには、生成する文字の最低文字数・最長文字数・色の生成方法・一文字毎に色を変えるかを渡せます。
下の書き方だと、4〜6文字をColorGeneratorを用いて生成することになります。
※RandomRangeColorGeneratorには、RGBAの範囲を指定できます。

ColorGenerator colorGenerator = new RandomRangeColorGenerator(new int[]{0,150},new int[]{0,150},new int[]{0,150},new int[]{255,255});
TextPaster textPaster = new RandomTextPaster(4,6,colorGenerator,true);

次に文字の変形方法です。
「ImageDeformation」インタフェースを実装した「ImageDeformationByFilters」を使用します。
ImageDeformationByFiltersには使用するImageFilterを指定します。
今回は「RippleFilter」を使用します。
※パラメータはいろいろ変えてみて下さい

RippleFilter filter1 = new RippleFilter();
filter1.setWaveType(RippleFilter.SINE);
//filter1.setWaveType(RippleFilter.SAWTOOTH);
//filter1.setWaveType(RippleFilter.TRIANGLE);
//filter1.setWaveType(RippleFilter.NOISE);
filter1.setXAmplitude(2);
filter1.setYAmplitude(2);
filter1.setXWavelength(5);
filter1.setYAmplitude(5);
//filter1.setEdgeAction(RippleFilter.ZERO);
//filter1.setEdgeAction(RippleFilter.WRAP);
filter1.setEdgeAction(RippleFilter.CLAMP);
ImageDeformation deformation = new ImageDeformationByFilters(new ImageFilter[]{filter1});

これで役者が揃いました。
実際にImageCaptchaServieを組み立てるまでのサンプルです。
背景の変形方法はテキストと同じ物を指定していますが、今回は白一色なので問題ないでしょう。

FileDictionary dictionary= new FileDictionary("mydictionay");
WordGenerator wordgen = new ComposeDictionaryWordGenerator(dictionary);

RippleFilter filter1 = new RippleFilter();
filter1.setWaveType(RippleFilter.SINE);
//filter1.setWaveType(RippleFilter.SAWTOOTH);
//filter1.setWaveType(RippleFilter.TRIANGLE);
//filter1.setWaveType(RippleFilter.NOISE);
filter1.setXAmplitude(2);
filter1.setYAmplitude(2);
filter1.setXWavelength(5);
filter1.setYAmplitude(5);
//filter1.setEdgeAction(RippleFilter.ZERO);
//filter1.setEdgeAction(RippleFilter.WRAP);
filter1.setEdgeAction(RippleFilter.CLAMP);

ImageDeformation deformation = new ImageDeformationByFilters(new ImageFilter[]{filter1});
FontGenerator fontGenerator = new RandomFontGenerator(40,50,new Font[]{new Font("MS ゴシック",0,10),new Font("MS 明朝",0,10),new Font("MS Pゴシック",0,10),new Font("MS P明朝",0,10)});

BackgroundGenerator backgroundGenerator = new UniColorBackgroundGenerator(300,100);

ColorGenerator colorGenerator = new RandomRangeColorGenerator(new int[]{0,150},new int[]{0,150},new int[]{0,150},new int[]{255,255});
TextPaster textPaster = new RandomTextPaster(4,6,colorGenerator,true);

WordToImage wordToImage = new DeformedComposedWordToImage(fontGenerator,backgroundGenerator,textPaster,deformation,deformation,deformation);

ImageCaptchaFactory factory = new GimpyFactory(wordgen,wordToImage);
CaptchaEngine engine = new GenericCaptchaEngine(new ImageCaptchaFactory[]{factory});
ImageCaptchaService instance = new GenericManageableCaptchaService(engine,300,200000);