⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 captchaimageresource.java

📁 Wicket一个开发Java Web应用程序框架。它使得开发web应用程序变得容易而轻松。 Wicket利用一个POJO data beans组件使得它可以与任何持久层技术相结合。
💻 JAVA
字号:
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements.  See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License.  You may obtain a copy of the License at * *      http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package org.apache.wicket.extensions.markup.html.captcha;import java.awt.BasicStroke;import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.awt.Shape;import java.awt.font.FontRenderContext;import java.awt.font.TextLayout;import java.awt.geom.AffineTransform;import java.awt.image.BufferedImage;import java.awt.image.WritableRaster;import java.lang.ref.SoftReference;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.Random;import org.apache.wicket.IClusterable;import org.apache.wicket.markup.html.image.resource.DynamicImageResource;import org.apache.wicket.util.time.Time;/** * Generates a captcha image. *  * @author Joshua Perlow */public final class CaptchaImageResource extends DynamicImageResource{	/**	 * This class is used to encapsulate all the filters that a character will get when rendered.	 * The changes are kept so that the size of the shapes can be properly recorded and reproduced	 * later, since it dynamically generates the size of the captcha image. The reason I did it this	 * way is because none of the JFC graphics classes are serializable, so they cannot be instance	 * variables here. If anyone knows a better way to do this, please let me know.	 */	private static final class CharAttributes implements IClusterable	{		private static final long serialVersionUID = 1L;		private char c;		private String name;		private int rise;		private double rotation;		private double shearX;		private double shearY;		CharAttributes(char c, String name, double rotation, int rise, double shearX, double shearY)		{			this.c = c;			this.name = name;			this.rotation = rotation;			this.rise = rise;			this.shearX = shearX;			this.shearY = shearY;		}		char getChar()		{			return c;		}		String getName()		{			return name;		}		int getRise()		{			return rise;		}		double getRotation()		{			return rotation;		}		double getShearX()		{			return shearX;		}		double getShearY()		{			return shearY;		}	}	private static final long serialVersionUID = 1L;	private static int randomInt(int min, int max)	{		return (int)(Math.random() * (max - min) + min);	}	private static String randomString(int min, int max)	{		int num = randomInt(min, max);		byte b[] = new byte[num];		for (int i = 0; i < num; i++)			b[i] = (byte)randomInt('a', 'z');		return new String(b);	}	private String challengeId;	private final List charAttsList;	private List fontNames = Arrays.asList(new String[] { "Helventica", "Arial", "Courier" });	private final int fontSize;	private final int fontStyle;	private int height = 0;	/** Transient image data so that image only needs to be generated once per VM */	private transient SoftReference imageData;	private final int margin;	private int width = 0;	/**	 * Construct.	 */	public CaptchaImageResource()	{		this(randomString(6, 8));	}	/**	 * Construct.	 * 	 * @param challengeId	 *            The id of the challenge	 */	public CaptchaImageResource(String challengeId)	{		this(challengeId, 48, 30);	}	/**	 * Construct.	 * 	 * @param challengeId	 *            The id of the challenge	 * @param fontSize	 *            The font size	 * @param margin	 *            The image's margin	 */	public CaptchaImageResource(String challengeId, int fontSize, int margin)	{		this.challengeId = challengeId;		this.fontStyle = 1;		this.fontSize = fontSize;		this.margin = margin;		this.width = this.margin * 2;		this.height = this.margin * 2;		char[] chars = challengeId.toCharArray();		charAttsList = new ArrayList();		TextLayout text;		AffineTransform textAt;		Shape shape;		for (int i = 0; i < chars.length; i++)		{			String fontName = (String)fontNames.get(randomInt(0, fontNames.size()));			double rotation = Math.toRadians(randomInt(-35, 35));			int rise = randomInt(margin / 2, margin);			Random ran = new Random();			double shearX = ran.nextDouble() * 0.2;			double shearY = ran.nextDouble() * 0.2;			CharAttributes cf = new CharAttributes(chars[i], fontName, rotation, rise, shearX,					shearY);			charAttsList.add(cf);			text = new TextLayout(chars[i] + "", getFont(fontName), new FontRenderContext(null,					false, false));			textAt = new AffineTransform();			textAt.rotate(rotation);			textAt.shear(shearX, shearY);			shape = text.getOutline(textAt);			this.width += (int)shape.getBounds2D().getWidth();			if (this.height < (int)shape.getBounds2D().getHeight() + rise)			{				this.height = (int)shape.getBounds2D().getHeight() + rise;			}		}	}	/**	 * Gets the id for the challenge.	 * 	 * @return The the id for the challenge	 */	public final String getChallengeId()	{		return challengeId;	}	/**	 * Causes the image to be redrawn the next time its requested.	 * 	 * @see org.apache.wicket.Resource#invalidate()	 */	public final void invalidate()	{		imageData = null;	}	/**	 * @see org.apache.wicket.markup.html.image.resource.DynamicImageResource#getImageData()	 */	protected final byte[] getImageData()	{		// get image data is always called in sync block		byte[] data = null;		if (imageData != null)		{			data = (byte[])imageData.get();		}		if (data == null)		{			data = render();			imageData = new SoftReference(data);			setLastModifiedTime(Time.now());		}		return data;	}	private Font getFont(String fontName)	{		return new Font(fontName, fontStyle, fontSize);	}	/**	 * Renders this image	 * 	 * @return The image data	 */	private final byte[] render()	{		while (true)		{			final BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);			Graphics2D gfx = (Graphics2D)image.getGraphics();			gfx.setBackground(Color.WHITE);			int curWidth = margin;			for (int i = 0; i < charAttsList.size(); i++)			{				CharAttributes cf = (CharAttributes)charAttsList.get(i);				TextLayout text = new TextLayout(cf.getChar() + "", getFont(cf.getName()), gfx						.getFontRenderContext());				AffineTransform textAt = new AffineTransform();				textAt.translate(curWidth, height - cf.getRise());				textAt.rotate(cf.getRotation());				textAt.shear(cf.getShearX(), cf.getShearY());				Shape shape = text.getOutline(textAt);				curWidth += shape.getBounds().getWidth();				gfx.setXORMode(Color.BLACK);				gfx.fill(shape);			}			// XOR circle			int dx = randomInt(width, 2 * width);			int dy = randomInt(width, 2 * height);			int x = randomInt(0, width / 2);			int y = randomInt(0, height / 2);			gfx.setXORMode(Color.BLACK);			gfx.setStroke(new BasicStroke(randomInt(fontSize / 8, fontSize / 2)));			gfx.drawOval(x, y, dx, dy);			WritableRaster rstr = image.getRaster();			int[] vColor = new int[3];			int[] oldColor = new int[3];			Random vRandom = new Random(System.currentTimeMillis());			// noise			for (x = 0; x < width; x++)			{				for (y = 0; y < height; y++)				{					rstr.getPixel(x, y, oldColor);					// hard noise					vColor[0] = 0 + (int)(Math.floor(vRandom.nextFloat() * 1.03) * 255);					// soft noise					vColor[0] = vColor[0] ^ (170 + (int)(vRandom.nextFloat() * 80));					// xor to image					vColor[0] = vColor[0] ^ oldColor[0];					vColor[1] = vColor[0];					vColor[2] = vColor[0];					rstr.setPixel(x, y, vColor);				}			}			return toImageData(image);		}	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -