|
|
package org.ros.chatto.captcha;
import javax.imageio.ImageIO;
import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random;
/** * This class represents a simple captcha consisting * of an image {@code png} and its text value. * Comic Neue Bold Font. * Capital english letters {@code ONLY}. * * @since 1.3 * @author Gennadiy Golovin */ public final class SimpleCaptcha {
private BufferedImage imagePng; private char[] text;
/** * Initializes a newly created default object * consisting of 8 capital english letters. */ public SimpleCaptcha() { this.text = getRandomChars();
try { generateCaptcha(); } catch (IOException e) { e.printStackTrace(); } }
/** * Initializes a newly created object, which length * depends on the passed {@code int} parameter, * which {@code MUST} be greater than 0. * If the condition is not met, initializes a newly * created default object consisting of 8 symbols. * * @param length the quantity of symbols, that the * captcha consists of, greater than 0. */ public SimpleCaptcha(int length) { if (length < 1) { this.text = getRandomChars(); } else { this.text = getRandomChars(length); }
try { generateCaptcha(); } catch (IOException e) { e.printStackTrace(); } }
/** * Initializes a newly created object based on the passed * {@link String} parameter, consisting of capital english * letters. If the condition is not met, initializes a newly * created default object consisting of 8 capital english letters. * * @param text the text string with the value of the captcha, * length greater than 0. */ public SimpleCaptcha(String text) { if (text == null || text.equals("")) { this.text = getRandomChars(); } else { this.text = text.toCharArray(); }
try { generateCaptcha(); } catch (IOException e) { this.text = getRandomChars(); try { generateCaptcha(); } catch (IOException ex) { ex.printStackTrace(); } } }
/** * Returns the picture with captcha * * @return {@link BufferedImage} */ public BufferedImage getImagePng() { return imagePng; }
/** * Returns the text value of the captcha * * @return {@link String} */ public String getText() { return String.valueOf(text); }
//////// //////// //////// //////// //////// //////// //////// ////////
private char[] getRandomChars() { return getRandomChars(8); }
private char[] getRandomChars(int quantity) {
char[] randomString = new char[quantity];
Random random = new Random();
int capitalLetter;
for (int i = 0; i < quantity; i++) { capitalLetter = 65 + random.nextInt(26); randomString[i] = (char) capitalLetter; }
return randomString; }
private void generateCaptcha() throws IOException { int charsQuantity = this.text.length; BufferedImage[] images = new BufferedImage[charsQuantity];
for (int i = 0; i < charsQuantity; i++) { images[i] = ImageIO.read(SimpleCaptcha.class.getResourceAsStream("/pictures/" + this.text[i] + ".png")); if (i % 2 == 0) { images[i] = rotateImage(images[i], 25); } else { images[i] = rotateImage(images[i], -20); } }
int imageSize = 30; int rotatedImageSize = (int) Math.sqrt(imageSize * imageSize * 2);
BufferedImage captchaImg = new BufferedImage(rotatedImageSize * (charsQuantity - 1) / 10 * 6 + rotatedImageSize, rotatedImageSize, BufferedImage.TYPE_INT_ARGB); Graphics2D graphics2d = captchaImg.createGraphics(); graphics2d.setBackground(Color.WHITE); graphics2d.clearRect(0, 0, captchaImg.getWidth(), captchaImg.getHeight()); for (int i = 0; i < charsQuantity; i++) { captchaImg.getGraphics().drawImage(images[i], rotatedImageSize * i / 10 * 6, 0, null); } graphics2d.dispose(); this.imagePng = captchaImg; }
private BufferedImage rotateImage(BufferedImage buffImage, double angle) {
double radian = Math.toRadians(angle); double sin = Math.abs(Math.sin(radian)); double cos = Math.abs(Math.cos(radian));
int width = buffImage.getWidth(); int height = buffImage.getHeight();
int nWidth = (int) Math.floor((double) width * cos + (double) height * sin); int nHeight = (int) Math.floor((double) height * cos + (double) width * sin);
BufferedImage rotatedImage = new BufferedImage(nWidth, nHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = rotatedImage.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC); graphics.translate((nWidth - width) / 2, (nHeight - height) / 2); graphics.rotate(radian, (double) (width / 2), (double) (height / 2)); graphics.drawImage(buffImage, 0, 0,null); graphics.dispose();
return rotatedImage; } }
|