public class SecurityCodeUtil {
private final static Logger logger = LoggerFactory.getLogger(SecurityCodeUtil.class);
// 驗證碼圖片的寬度。
private final static int WIDTH = 120;
// 驗證碼圖片的高度。
private final static int HEIGHT = 40;
// 驗證碼干擾線數
private final static int INTERFERENCE_LINE_COUNT = 10;
private final static String RANDOM_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890";
private final static int MIN_WIDTH = 20;
// 得到隨機字符
public static String randomString(int n) {
Random random = new Random(System.currentTimeMillis());
StringBuffer rnd = new StringBuffer();
String chars = RANDOM_CHARS;
int len = chars.length() - 1;
double r;
for (int i = 0; i < n; i++) {
r = (random.nextDouble()) * len;
rnd.append(chars.charAt((int) r));
}
return rnd.toString();
}
public static byte[] drawImg(String securityCode) {
// 16k
ByteArrayOutputStream out = new ByteArrayOutputStream(16 * 1024);
Graphics2D g = null;
try {
int fontWidth = WIDTH / securityCode.length();// 字體的寬度
if (fontWidth < MIN_WIDTH) {
throw new RuntimeException("字符過多");
}
int fontHeight = HEIGHT - 5;// 字體的高度
int codeY = HEIGHT - 8;
// 圖像buffer
BufferedImage buffImg = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
// Graphics g = buffImg.getGraphics();
g = buffImg.createGraphics();
// 設置背景色
// g.setColor(getRandColor(200, 250));
g.setColor(new Color(255, 255, 255));
g.fillRect(0, 0, WIDTH, HEIGHT);
g.setColor(new Color(204, 204, 204));
g.drawRect(0, 0, WIDTH - 1, HEIGHT - 1);
// 設置字體
// Font font = getFont(fontHeight);
Font font = new Font("Fixedsys", Font.PLAIN, fontHeight);
g.setFont(font);
Random random = new Random();
// 設置干擾線
for (int i = 0; i < INTERFERENCE_LINE_COUNT; i++) {
int xs = random.nextInt(WIDTH);
int ys = random.nextInt(HEIGHT);
int xe = xs + random.nextInt(WIDTH);
int ye = ys + random.nextInt(HEIGHT);
g.setColor(randColor(1, 255));
g.drawLine(xs, ys, xe, ye);
}
// 添加噪點
float yawpRate = 0.01f;// 噪聲率
int area = (int) (yawpRate * WIDTH * HEIGHT);
area = 8;
for (int i = 0; i < area; i++) {
int x = random.nextInt(WIDTH);
int y = random.nextInt(HEIGHT);
buffImg.setRGB(x, y, random.nextInt(255));
}
// 得到隨機字符
char[] codeChars = securityCode.toCharArray();
for (int i = 0; i < codeChars.length; i++) {
char strRand = codeChars[i];
g.setColor(randColor(1, 255));
// g.drawString(a,x,y);
// a爲要畫出來的東西,x和y表示要畫的東西最左側字符的基線位於此圖形上下文座標系的 (x, y) 位置處
g.drawString(String.copyValueOf(new char[] { strRand }), i * fontWidth + 1, codeY);
}
ImageIO.write(buffImg, "JPEG", out);
return out.toByteArray();
} catch (Exception e) {
logger.error("驗證碼生產失敗!", e);
} finally {
if (g != null) {
g.dispose();
}
try {
out.close();
} catch (IOException e) {
logger.error("", e);
}
}
return new byte[0];
}
/**
* 隨機顏色
*
* @param fc 給定範圍獲得隨機顏色
* @param bc 給定範圍獲得隨機顏色
* @return
*/
private static Color randColor(int fc, int bc) {
Random random = new Random(System.currentTimeMillis());
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);
}
}
對應的Response只要設置返回類型就行
response.setContentType("image/jpeg");
response.addHeader("Accept-Ranges", "bytes");