1
2
3
4
5
6
7 package com.octo.captcha.image.fisheye;
8
9 import com.octo.captcha.CaptchaException;
10 import com.octo.captcha.CaptchaQuestionHelper;
11 import com.octo.captcha.component.image.backgroundgenerator.BackgroundGenerator;
12 import com.octo.captcha.component.image.deformation.ImageDeformation;
13 import com.octo.captcha.image.ImageCaptcha;
14 import com.octo.captcha.image.ImageCaptchaFactory;
15
16 import java.awt.*;
17 import java.awt.image.BufferedImage;
18 import java.security.SecureRandom;
19 import java.util.Locale;
20 import java.util.Random;
21
22 /***
23 * This factory use a Backgroud generator to retrieve a picture, Selects a random square center for the deformation, and
24 * apply it.
25 *
26 * @author <a href="mailto:mag@jcaptcha.net">Marc-Antoine Garrigue</a>
27 * @version 1.0
28 */
29 public class FishEyeFactory extends ImageCaptchaFactory {
30
31 public static final String BUNDLE_QUESTION_KEY = FishEye.class.getName();
32
33 private Random myRandom = new SecureRandom();
34 private BackgroundGenerator generator;
35 private ImageDeformation deformation;
36 private Integer tolerance;
37 private Integer scale;
38
39 /***
40 * Construct a new fishEye factory
41 *
42 * @param generator the picture generator
43 * @param deformation a deformation to be apply on the background
44 * @param scale the size of the defprmed part (percent)
45 * @param tolerance the tolerence (see FishEye)
46 * @see FishEye
47 */
48 public FishEyeFactory(BackgroundGenerator generator,
49 ImageDeformation deformation, Integer scale,
50 Integer tolerance) {
51 if (generator == null) {
52 throw new CaptchaException("Invalid configuration for a FishEyeFactory "
53 + ": BackgroundGenerator can't be null");
54 }
55 if (deformation == null) {
56 throw new CaptchaException("Invalid configuration "
57 + "for a FishEyeFactory : ImageDeformation"
58 + " can't be null");
59 }
60 this.deformation = deformation;
61 this.generator = generator;
62 if (scale == null || scale.intValue() < 1 || scale.intValue() > 99) {
63 throw new CaptchaException("Invalid configuration for a"
64 + " FishEyeFactory : scale"
65 + " can't be null, and must be between 1 and 99");
66 }
67 this.scale = scale;
68 if (tolerance == null || tolerance.intValue() < 0) {
69 throw new CaptchaException("Invalid configuration for"
70 + " a FishEyeFactory : tolerance"
71 + " can't be null, and must be positive");
72 }
73
74 this.tolerance = tolerance;
75 }
76
77 /***
78 * gimpies are ImageCaptcha
79 *
80 * @return the image captcha with default locale
81 */
82 public ImageCaptcha getImageCaptcha() {
83 return getImageCaptcha(Locale.getDefault());
84 }
85
86 /***
87 * gimpies are ImageCaptcha
88 *
89 * @return a pixCaptcha with the question :"spell the word"
90 */
91 public ImageCaptcha getImageCaptcha(Locale locale) {
92 BufferedImage background = generator.getBackground();
93 BufferedImage out = new BufferedImage(background.getWidth(),
94 background.getHeight(), background.getType());
95 out.getGraphics().drawImage(background, 0, 0, null, null);
96 int x = background.getWidth();
97 int y = background.getHeight();
98
99
100 int scaledX = Math.max(x * scale.intValue() / 100, 1);
101 int scaledY = Math.max(y * scale.intValue() / 100, 1);
102 int xPos = myRandom.nextInt(x - scaledX);
103 int yPos = myRandom.nextInt(y - scaledY);
104 BufferedImage clone = out.getSubimage(xPos, yPos, scaledX, scaledY);
105 out.getGraphics().drawImage(deformation.deformImage(clone), xPos, yPos,
106 Color.white, null);
107 out.getGraphics().dispose();
108 Point center = new Point(xPos + (scaledX / 2), yPos + (scaledY / 2));
109
110 return new FishEye(CaptchaQuestionHelper.getQuestion(locale, BUNDLE_QUESTION_KEY),
111 out, center, tolerance);
112 }
113
114 }