package me.test.kaptcha;
import com.google.code.kaptcha.NoiseProducer;
import com.google.code.kaptcha.util.Configurable;
import java.awt.*;
import java.awt.geom.CubicCurve2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.image.BufferedImage;
import java.util.Random;
/**
* The default implementation of {@link com.google.code.kaptcha.NoiseProducer}, adds a noise on an
* image.
* 基于kaptcha的DefaultNoise,干扰线宽度+2。
*/
public class NoiseImpl 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 Random();
// 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.9f * (4 - i)+2));
graph.drawLine((int) pts[i].getX(), (int) pts[i].getY(),
(int) pts[i + 1].getX(), (int) pts[i + 1].getY());
}
graph.dispose();
}
}