This article shares the Java version of the imitation QQ verification code style image verification code for everyone. The specific content is as follows
Features include: custom image size and character length, random background color and character color, random character offset angle, character smooth edge, interference lines, noise, background distortion.
I originally wanted to make characters twisted, but I don’t know why the teacher wrote the text and then reported the error. Let’s do it for now. I hope a master can help correct it.
It should be noted that the reason why there is a bit like QQ verification code is because of this Algerian font. If the system does not have one, you need to install it yourself. You can download the font name on Baidu and just throw away the system Fonts folder.
Reproduction image:
package hh.com.util; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; public class AuthImage extends javax.servlet.http.HttpServlet implements javax.servlet.Servlet { static final long serialVersionUID = 1L; public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Pragma", "No-cache"); response.setHeader("Cache-Control", "no-cache"); response.setDateHeader("Expires", 0); response.setContentType("image/jpeg"); //Generate random string String verifyCode = VerifyCodeUtils.generateVerifyCode(4); //Save session session HttpSession session = request.getSession(true); session.setAttribute("rand", verifyCode.toLowerCase()); //Generate image int w = 200, h = 80; VerifyCodeUtils.outputImage(w, h, response.getOutputStream(), verifyCode); }} VerifyCodeUtils class
package hh.com.util; import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.LinearGradientPaint;import java.awt.Paint;import java.awt.RenderingHints;import java.awt.geom.AffineTransform;import java.awt.image.BufferedImage;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;import java.util.Arrays;import java.util.Random; import javax.imageio.ImageIO; public class VerifyCodeUtils{ //Use the Algerian font, if it is not in the system, the font only displays capitalization, and removes several easily confusing characters of 1,0,i,o public static final String VERIFY_CODES = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ"; private static Random random = new Random(); /** * Use the system default character source to generate verification code* @param verifySize Verification code length* @return */ public static String generateVerifyCode(int verifySize, VERIFY_CODES); } /** * Use the specified source to generate verification code* @param verifySize Verification code length* @param sources Verification code character source* @return */ public static String generateVerifyCode(int verifySize, String sources){ if(sources == null || sources.length() == 0){ sources = VERIFY_CODES; } int codesLen = sources.length(); Random rand = new Random(System.currentTimeMillis()); StringBuilder verifyCode = new StringBuilder(verifySize); for(int i = 0; i < verifySize; i++){ verifyCode.append(sources.charAt(rand.nextInt(codesLen-1))); } return verifyCode.toString(); } /** * Generate a random verification code file and return the verification code value* @param w * @param h * @param outputFile * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException{ String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, outputFile, verifyCode); return verifyCode; } /** * Output the random verification code image stream and return the verification code value* @param w * @param h * @param os * @param verifySize * @return * @throws IOException */ public static String outputVerifyImage(int w, int h, OutputStream os, int verifySize) throws IOException{ String verifyCode = generateVerifyCode(verifySize); outputImage(w, h, os, verifyCode); return verifyCode; } /** * Generate the specified verification code image file* @param w * @param h * @param outputFile * @param code * @throws IOException */ public static void outputImage(int w, int h, File outputFile, String code) throws IOException{ if(outputFile == null){ return; } File dir = outputFile.getParentFile(); if(!dir.exists()){ dir.mkdir(); } try{ outputFile.createNewFile(); FileOutputStream fos = new FileOutputStream(outputFile); outputImage(w, h, fos, code); fos.close(); } catch(IOException e){ throw e; } } /** * Output specified verification code image stream* @param w * @param h * @param os * @param code * @throws IOException */ public static void outputImage(int w, int h, OutputStream os, String code) throws IOException{ int verifySize = code.length(); BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB); Random rand = new Random(); Graphics2D g2 = image.createGraphics(); g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON); Color[] colors = new Color[5]; Color[] colorSpaces = new Color[] { Color.WHITE, Color.CYAN, Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.YELLOW }; float[] fractions = new float[colors.length]; for(int i = 0; i < colors.length; i++){ colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)]; fractions[i] = rand.nextFloat(); } Arrays.sort(fractions); g2.setColor(Color.GRAY);// Set border color g2.fillRect(0, 0, w, h); Color c = getRandColor(200, 250); g2.setColor(c);// Set background color g2.fillRect(0, 2, w, h-4); // Draw interference line Random random = new Random(); g2.setColor(getRandColor(160, 200));// Set color of the line for (int i = 0; i < 20; i++) { int x = random.nextInt(w - 1); int y = random.nextInt(h - 1); int xl = random.nextInt(6) + 1; int yl = random.nextInt(12) + 1; g2.drawLine(x, y, x + xl + 40, y + yl + 20); } // Add noise float yawpRate = 0.05f;// Noise rate int area = (int) (yawpRate * w * h); for (int i = 0; i < area; i++) { int x = random.nextInt(w); int y = random.nextInt(h); int rgb = getRandomIntColor(); image.setRGB(x, y, rgb); } shear(g2, w, h, c);// distort the picture g2.setColor(getRandColor(100, 160)); int fontSize = h-4; Font font = new Font("Algerian", Font.ITALIC, fontSize); g2.setFont(font); char[] chars = code.toCharArray(); for(int i = 0; i < verifySize; i++){ AffineTransform affine = new AffineTransform(); affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize/2, h/2); g2.setTransform(affine); g2.drawChars(chars, i, 1, ((w-10) / verifySize) * i + 5, h/2 + fontSize/2 - 10); } g2.dispose(); ImageIO.write(image, "jpg", os); } private static Color getRandColor(int fc, int bc) { if (fc > 255) fc = 255; if (bc > 255) bc = 255; int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } private static int getRandomIntColor() { int[] rgb = getRandomRgb(); int color = 0; for (int c : rgb) { color = color << 8; color = color | c; } return color; } private static int[] getRandomRgb() { int[] rgb = new int[3]; for (int i = 0; i < 3; i++) { rgb[i] = random.nextInt(255); } return rgb; } private static void shear(Graphics g, int w1, int h1, Color color) { shearX(g, w1, h1, color); shearY(g, w1, h1, color); } private static void shearX(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(2); boolean borderGap = true; int frames = 1; int phase = random.nextInt(2); for (int i = 0; i < h1; i++) { double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(0, i, w1, 1, (int) d, 0); if (borderGap) { g.setColor(color); g.drawLine((int) d, i, 0, i); g.drawLine((int) d + w1, i, w1, i); } } } private static void shearY(Graphics g, int w1, int h1, Color color) { int period = random.nextInt(40) + 10; // 50; boolean borderGap = true; int frames = 20; int phase = 7; for (int i = 0; i < w1; i++) { double d = (double) (period >> 1) * Math.sin((double) i / (double) period + (6.2831853071795862D * (double) phase) / (double) frames); g.copyArea(i, 0, 1, h1, 0, (int) d); if (borderGap) { g.setColor(color); g.drawLine(i, (int) d, i, 0); g.drawLine(i, (int) d + h1, i, h1); } } } public static void main(String[] args) throws IOException{ File dir = new File("F:/verifier"); int w = 200, h = 80; for(int i = 0; i < 50; i++){ String verifyCode = generateVerifyCode(4); File file = new File(dir, verifyCode + ".jpg"); outputImage(w, h, file, verifyCode); } }} web.xml configuration:
<servlet> <servlet-name>AuthImage</servlet-name> <servlet-class>hh.com.util.AuthImage</servlet-class> </servlet> <servlet-mapping> <servlet-name>AuthImage</servlet-name> <url-pattern>/authImage</url-pattern> </servlet-mapping>
The above is all about this article. I hope it will inspire you to learn Java image verification code.