RandomColor captcha
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package com.google.code.kaptcha.impl;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.geom.CubicCurve2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Random;
|
||||
|
||||
import com.google.code.kaptcha.NoiseProducer;
|
||||
import com.google.code.kaptcha.util.Configurable;
|
||||
|
||||
/**
|
||||
* The default implementation of {@link NoiseProducer}, adds a noise on an
|
||||
* image.
|
||||
*/
|
||||
public class LightNoise extends Configurable implements NoiseProducer
|
||||
{
|
||||
/**
|
||||
* Draws a noise on the image. The noise curve depends on the factor values.
|
||||
* Noise won't be visible if all factors have the value > 1.0f
|
||||
*
|
||||
* @param image
|
||||
* the image to add the noise to
|
||||
* @param factorOne
|
||||
* @param factorTwo
|
||||
* @param factorThree
|
||||
* @param factorFour
|
||||
*/
|
||||
public void makeNoise(BufferedImage image, float factorOne,
|
||||
float factorTwo, float factorThree, float factorFour)
|
||||
{
|
||||
Color color = getConfig().getNoiseColor();
|
||||
|
||||
// image size
|
||||
int width = image.getWidth();
|
||||
int height = image.getHeight();
|
||||
|
||||
// the points where the line changes the stroke and direction
|
||||
Point2D[] pts = null;
|
||||
Random rand = new SecureRandom();
|
||||
|
||||
// the curve from where the points are taken
|
||||
CubicCurve2D cc = new CubicCurve2D.Float(width * factorOne, height
|
||||
* rand.nextFloat(), width * factorTwo, height
|
||||
* rand.nextFloat(), width * factorThree, height
|
||||
* rand.nextFloat(), width * factorFour, height
|
||||
* rand.nextFloat());
|
||||
|
||||
// creates an iterator to define the boundary of the flattened curve
|
||||
PathIterator pi = cc.getPathIterator(null, 2);
|
||||
Point2D tmp[] = new Point2D[200];
|
||||
int i = 0;
|
||||
|
||||
// while pi is iterating the curve, adds points to tmp array
|
||||
while (!pi.isDone())
|
||||
{
|
||||
float[] coords = new float[6];
|
||||
switch (pi.currentSegment(coords))
|
||||
{
|
||||
case PathIterator.SEG_MOVETO:
|
||||
case PathIterator.SEG_LINETO:
|
||||
tmp[i] = new Point2D.Float(coords[0], coords[1]);
|
||||
}
|
||||
i++;
|
||||
pi.next();
|
||||
}
|
||||
|
||||
pts = new Point2D[i];
|
||||
System.arraycopy(tmp, 0, pts, 0, i);
|
||||
|
||||
Graphics2D graph = (Graphics2D) image.getGraphics();
|
||||
graph.setRenderingHints(new RenderingHints(
|
||||
RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON));
|
||||
|
||||
graph.setColor(color);
|
||||
|
||||
// for the maximum 3 point change the stroke and direction
|
||||
for (i = 0; i < pts.length - 1; i++)
|
||||
{
|
||||
if (i < 3)
|
||||
graph.setStroke(new BasicStroke(0.7f * (2 - i)));
|
||||
graph.drawLine((int) pts[i].getX(), (int) pts[i].getY(),
|
||||
(int) pts[i + 1].getX(), (int) pts[i + 1].getY());
|
||||
}
|
||||
|
||||
graph.dispose();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package com.google.code.kaptcha.impl;
|
||||
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import com.google.code.kaptcha.GimpyEngine;
|
||||
import com.google.code.kaptcha.NoiseProducer;
|
||||
import com.google.code.kaptcha.util.Configurable;
|
||||
import com.jhlabs.image.RippleFilter;
|
||||
import com.jhlabs.image.TransformFilter;
|
||||
import com.jhlabs.image.WaterFilter;
|
||||
|
||||
/**
|
||||
* {@link WaterRipple} adds water ripple effect to an image.
|
||||
*/
|
||||
public class Ripple extends Configurable implements GimpyEngine
|
||||
{
|
||||
/**
|
||||
* Applies distortion by adding water ripple effect.
|
||||
*
|
||||
* @param baseImage the base image
|
||||
* @return the distorted image
|
||||
*/
|
||||
public BufferedImage getDistortedImage(BufferedImage baseImage)
|
||||
{
|
||||
NoiseProducer noiseProducer = getConfig().getNoiseImpl();
|
||||
BufferedImage distortedImage = new BufferedImage(baseImage.getWidth(),
|
||||
baseImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
|
||||
Graphics2D graphics = (Graphics2D) distortedImage.getGraphics();
|
||||
|
||||
RippleFilter rippleFilter = new RippleFilter();
|
||||
rippleFilter.setWaveType(RippleFilter.SINE);
|
||||
rippleFilter.setXAmplitude(2.6f);
|
||||
rippleFilter.setYAmplitude(1.7f);
|
||||
rippleFilter.setXWavelength(15);
|
||||
rippleFilter.setYWavelength(5);
|
||||
rippleFilter.setEdgeAction(TransformFilter.NEAREST_NEIGHBOUR);
|
||||
|
||||
BufferedImage effectImage = rippleFilter.filter(baseImage, null);
|
||||
|
||||
graphics.drawImage(effectImage, 0, 0, null, null);
|
||||
|
||||
graphics.dispose();
|
||||
|
||||
noiseProducer.makeNoise(distortedImage, .1f, .1f, .25f, .25f);
|
||||
noiseProducer.makeNoise(distortedImage, .1f, .25f, .5f, .9f);
|
||||
return distortedImage;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package com.google.code.kaptcha.text.impl;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
import com.google.code.kaptcha.text.WordRenderer;
|
||||
import com.google.code.kaptcha.util.ConfigHelper;
|
||||
import com.google.code.kaptcha.util.Configurable;
|
||||
|
||||
/**
|
||||
* The default implementation of {@link WordRenderer}, creates an image with a
|
||||
* word rendered on it.
|
||||
*/
|
||||
public class RandomColorWordRenderer extends Configurable implements WordRenderer
|
||||
{
|
||||
ConfigHelper configHelper = new ConfigHelper();
|
||||
/**
|
||||
* Renders a word to an image.
|
||||
*
|
||||
* @param word
|
||||
* The word to be rendered.
|
||||
* @param width
|
||||
* The width of the image to be created.
|
||||
* @param height
|
||||
* The height of the image to be created.
|
||||
* @return The BufferedImage created from the word.
|
||||
*/
|
||||
public BufferedImage renderWord(String word, int width, int height)
|
||||
{
|
||||
int fontSize = getConfig().getTextProducerFontSize();
|
||||
Font[] fonts = getConfig().getTextProducerFonts(fontSize);
|
||||
Color color = getConfig().getTextProducerFontColor();
|
||||
int charSpace = getConfig().getTextProducerCharSpace();
|
||||
BufferedImage image = new BufferedImage(width, height,
|
||||
BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g2D = image.createGraphics();
|
||||
g2D.setColor(color);
|
||||
|
||||
RenderingHints hints = new RenderingHints(
|
||||
RenderingHints.KEY_ANTIALIASING,
|
||||
RenderingHints.VALUE_ANTIALIAS_ON);
|
||||
hints.add(new RenderingHints(RenderingHints.KEY_RENDERING,
|
||||
RenderingHints.VALUE_RENDER_QUALITY));
|
||||
g2D.setRenderingHints(hints);
|
||||
|
||||
FontRenderContext frc = g2D.getFontRenderContext();
|
||||
Random random = new SecureRandom();
|
||||
|
||||
int startPosY = (height - fontSize) / 5 + fontSize;
|
||||
|
||||
char[] wordChars = word.toCharArray();
|
||||
Font[] chosenFonts = new Font[wordChars.length];
|
||||
int [] charWidths = new int[wordChars.length];
|
||||
int widthNeeded = 0;
|
||||
for (int i = 0; i < wordChars.length; i++)
|
||||
{
|
||||
|
||||
//chosenFonts[i] = new Font("Arial", Font.BOLD, fontSize);
|
||||
//random
|
||||
chosenFonts[i] = fonts[random.nextInt(fonts.length)];
|
||||
|
||||
char[] charToDraw = new char[]{
|
||||
wordChars[i]
|
||||
};
|
||||
GlyphVector gv = chosenFonts[i].createGlyphVector(frc, charToDraw);
|
||||
charWidths[i] = (int)gv.getVisualBounds().getWidth();
|
||||
if (i > 0)
|
||||
{
|
||||
widthNeeded = widthNeeded + 2;
|
||||
}
|
||||
widthNeeded = widthNeeded + charWidths[i];
|
||||
}
|
||||
|
||||
HashMap<String,String> selectedColor =new HashMap<String,String>();
|
||||
int startPosX = (width - widthNeeded) / 2;
|
||||
|
||||
for (int i = 0; i < wordChars.length; i++)
|
||||
{
|
||||
String randomcolor="";
|
||||
do {
|
||||
randomcolor=COLOR_LIST[random.nextInt(COLOR_LIST.length)].replaceAll(" ", "");
|
||||
}while(selectedColor.containsKey(randomcolor));
|
||||
|
||||
selectedColor.put(randomcolor, randomcolor);
|
||||
|
||||
color = configHelper.getColor(randomcolor, randomcolor, Color.LIGHT_GRAY);
|
||||
g2D.setColor(color);
|
||||
|
||||
g2D.setFont(chosenFonts[i]);
|
||||
|
||||
char[] charToDraw = new char[] {
|
||||
wordChars[i]
|
||||
};
|
||||
|
||||
//System.out.println(charToDraw[0] +" - "+chosenFonts[i]);
|
||||
g2D.drawChars(charToDraw, 0, charToDraw.length, startPosX, startPosY);
|
||||
startPosX = startPosX + (int) charWidths[i] + charSpace;
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
static String [] COLOR_LIST = {
|
||||
//"255, 255, 255",//white
|
||||
//"192, 192, 192",//silver
|
||||
//"128, 128, 128",//gray
|
||||
"0, 0, 0",//black
|
||||
"255, 0, 0",//red
|
||||
"128, 0, 0",//maroon
|
||||
"255, 255, 0",//yellow
|
||||
"128, 128, 0",//olive
|
||||
"0, 255, 0",//lime
|
||||
"0, 128, 0",//green
|
||||
"0, 255, 255",//aqua
|
||||
"0, 128, 128",//teal
|
||||
"0, 0, 255",//blue
|
||||
"0, 0, 128",//navy
|
||||
"255, 0, 255",//fuchsia
|
||||
"128, 0, 128"//purple
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
kaptcha.image.width=80
|
||||
kaptcha.image.height=25
|
||||
kaptcha.border=no
|
||||
#kaptcha.obscurificator.impl=com.google.code.kaptcha.impl.ShadowGimpy
|
||||
kaptcha.obscurificator.impl=com.google.code.kaptcha.impl.Ripple
|
||||
kaptcha.textproducer.font.size=23
|
||||
kaptcha.textproducer.char.string=0123456789
|
||||
kaptcha.textproducer.char.length=4
|
||||
kaptcha.textproducer.char.space=3
|
||||
#kaptcha.noise.impl=com.google.code.kaptcha.impl.DefaultNoise
|
||||
kaptcha.noise.impl=com.google.code.kaptcha.impl.LightNoise
|
||||
#kaptcha.noise.color=white
|
||||
kaptcha.word.impl=com.google.code.kaptcha.text.impl.RandomColorWordRenderer
|
||||
Reference in New Issue
Block a user