View Javadoc

1   /*
2    * JCaptcha, the open source java framework for captcha definition and integration
3    * Copyright (c)  2007 jcaptcha.net. All Rights Reserved.
4    * See the LICENSE.txt file distributed with this package.
5    */
6   
7   package com.octo.captcha.component.image.deformation;
8   
9   import com.jhlabs.image.RotateFilter;
10  import com.octo.captcha.component.image.utils.ToolkitFactory;
11  
12  import java.awt.*;
13  import java.awt.image.BufferedImage;
14  import java.awt.image.FilteredImageSource;
15  import java.awt.image.ImageFilter;
16  import java.security.SecureRandom;
17  import java.util.Random;
18  
19  /***
20   * Deformation where the image is divided in little squares, moved individualty in a random position. Each move is
21   * really light, in order to let the captcha readble.
22   *
23   * @author Benoit Doumas
24   */
25  public class PuzzleImageDeformation implements ImageDeformation {
26  
27      /***
28       * Number of colums to divide the image, max number if rows and colums are managed randomly
29       */
30      private int colNum = 6;
31  
32      /***
33       * Number of rows to divide the image, max number if rows and colums are managed randomly
34       */
35      private int rowNum = 4;
36  
37      /***
38       * Maximal angle of rotation for each square.
39       */
40      private double maxAngleRotation = 0.3;
41  
42      private Random random = new SecureRandom();
43  
44      /***
45       * Conststruct a PuzzleImageDeformation, with the numbers of colums and rows. If manageRowAndColRandomly is set to
46       * true, the numbers of rows and colums are choosed between 1 and colNum/rowNum
47       *
48       * @param colNum                  Number of colums to divide the image, max number if rows and colums are managed
49       *                                randomly
50       * @param rowNum                  Number of rows to divide the image, max number if rows and colums are managed
51       *                                randomly
52       * @param maxAngleRotation        Maximal angle of rotation for each square.
53       */
54      public PuzzleImageDeformation(int colNum, int rowNum, double maxAngleRotation) {
55          super();
56          this.colNum = colNum;
57          this.rowNum = rowNum;
58          this.maxAngleRotation = maxAngleRotation;
59      }
60  
61      /*
62       * @see com.octo.captcha.component.image.deformation.ImageDeformation#deformImage(java.awt.image.BufferedImage)
63       */
64      public BufferedImage deformImage(BufferedImage image) {
65  
66          int height = image.getHeight();
67          int width = image.getWidth();
68  
69          int xd = width / colNum;
70          int yd = height / rowNum;
71  
72          BufferedImage backround = new BufferedImage(width, height, image.getType());
73          Graphics2D pie = (Graphics2D) backround.getGraphics();
74  
75          pie.setColor(Color.white);
76          pie.setBackground(Color.white);
77          pie.fillRect(0, 0, width, height);
78          pie.dispose();
79  
80          Graphics2D g = (Graphics2D) image.getGraphics();
81          g.setBackground(Color.white);
82  
83          BufferedImage smallPart = new BufferedImage(xd, yd, image.getType());
84          Graphics2D gSmall = smallPart.createGraphics();
85          FilteredImageSource filtered;
86  
87          for (int i = 0; i < colNum; i++) {
88              for (int j = 0; j < rowNum; j++) {
89                  gSmall.drawImage(image, 0, 0, xd, yd, xd * i, yd * j, xd * i + xd, yd * j + yd,
90                          null);
91  
92                  RotateFilter filter = new RotateFilter((float)maxAngleRotation * random.nextFloat()
93                          * (random.nextBoolean() ? -1 : 1));
94                //  TODO
95                  //filtered = new FilteredImageSource(smallPart.getSource(), filter);
96                 // Image temp = ToolkitFactory.getToolkit().createImage(filtered);
97                //  smallPart.getGraphics().drawImage(temp, 0, 0, new Color(0, 0, 0, 0), null);
98  
99                  smallPart.getGraphics().dispose();
100 
101                 g.drawImage(smallPart, xd * i, yd * j, null, null);
102             }
103         }
104 
105         return image;
106     }
107 
108 }