首先,我们先来看本地如何生成图片验证码的,再来写输出到网页的验证码如何实现。

先来看最简单的—实现的功能是,将一个字符串变成图片写入到文件中

实现代码:

package cn.hncu.img;

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException; import javax.imageio.ImageIO;
//该类包含一些用来查找 ImageReader 和 ImageWriter 以及执行简单编码和解码的静态便捷方法。 import org.junit.Test; public class ImgDemo { //学习如何把一个字符串变成图片写到一个文件
@Test
public void ImgDemo1() throws FileNotFoundException, IOException{
BufferedImage img = new BufferedImage(60, 30, BufferedImage.TYPE_INT_RGB);
// 表示一个图像,它具有合成整数像素的 8 位 RGB 颜色分量。
Graphics g = img.getGraphics();
g.drawString("Hello",10,20);
//使用此图形上下文的当前字体和颜色绘制由指定 string 给定的文本。最左侧字符的基线位于此图形上下文坐标系的 (x, y) 位置处。
g.dispose();////类似于流中的close()带动flush()---把数据刷到img对象当中
//释放此图形的上下文以及它使用的所有系统资源。调用 dispose 之后,就不能再使用 Graphics 对象。
ImageIO.write(img, "JPG", new FileOutputStream("img/a.jpg"));
//使用支持给定格式的任意 ImageWriter 将一个图像写入 File。
} }

结果:

上面那个很简单,对不对,我们看到的验证码都不是这样的,那好,我们给它加点干扰线,背景色,字符和y坐标随机生成。

有干扰线、背景色的验证码-写入文件

演示代码:

package cn.hncu.img;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Random; import javax.imageio.ImageIO;
//该类包含一些用来查找 ImageReader 和 ImageWriter 以及执行简单编码和解码的静态便捷方法。 import org.junit.Test; public class ImgDemo {
//把上面的字符串改成我们平时用的验证码---生成几个随机数字,有背景色和干扰线
@Test
public void ImgDemo2() throws FileNotFoundException, IOException{
int width = 80;
int height= 40;
int lines = 10;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = img.getGraphics(); //设置背景色
g.setColor(Color.white);
g.fillRect(0, 0, width, height);//画背景
//填充指定的矩形。使用图形上下文的当前颜色填充该矩形 //设置字体
g.setFont(new Font("宋体", Font.BOLD, 18)); //随机数字
Date d = new Date();
//System.out.println(d.getTime());
Random r = new Random(d.getTime());
for(int i=0;i<4;i++){
int a = r.nextInt(10);//取10以内的整数[0,9]
int y = 10+r.nextInt(20); //10~30范围内的一个整数,作为y坐标
Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
g.setColor(c);
g.drawString(""+a, 5+i*width/4, y);
}
//干扰线
for(int i=0;i<lines;i++){
Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
g.setColor(c);
g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
} g.dispose();//类似于流中的close()带动flush()---把数据刷到img对象当中
ImageIO.write(img, "JPG", new FileOutputStream("img/b.jpg")); } }

演示结果:

最后来看一个可以旋转和放缩的验证码-写到图片本地文件中

演示代码:

package cn.hncu.img;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import java.util.Random; import javax.imageio.ImageIO;
//该类包含一些用来查找 ImageReader 和 ImageWriter 以及执行简单编码和解码的静态便捷方法。 import org.junit.Test; public class ImgDemo {
@Test//可以旋转和放缩的验证码
public void ImgDemo3() throws FileNotFoundException, IOException{
int width = 80;
int height = 40;
int lines = 10;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D)img.getGraphics(); g2d.setFont(new Font("宋体", Font.BOLD, 20)); Random r = new Random(new Date().getTime()); //设置背景色
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.drawRect(0, 0, width, height);//绘制指定矩形的边框。
g2d.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255)));
g2d.fillRect(0, 0, width, height);//填充指定的矩形。 for(int i=0;i<4;i++){
String str = ""+r.nextInt(10); //处理旋转
AffineTransform Tx = new AffineTransform();
Tx.rotate(Math.random(), 5+i*15, height-5);
//用弧度测量的旋转角度,旋转锚点的 X 坐标,旋转锚点的 Y 坐标
//Tx.scale(0.7+Math.random(), 0.7+Math.random());
//x坐标方向的缩放倍数,y坐标方向的缩放倍数
g2d.setTransform(Tx);
Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
g2d.setColor(c);
g2d.drawString(str, 2+i*width/4, height-13);
} //干扰线
for(int i=0;i<lines;i++){
Color c = new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255));
g2d.setColor(c);
g2d.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
} g2d.dispose(); ImageIO.write(img, "JPG", new FileOutputStream("img/c.jpg"));
}
}

演示结果:

下面就要开始演示前台的图片验证技术了。

前台的图片验证技术

这个项目的结构图:

index.jsp:

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript">
function changImg(){
var img = document.getElementById("servletImg");
var d = new Date();
var time = d.getTime();//如果没有这个
//下面这一句不会起作用,因为浏览器的缓存技术,图片并不会刷新
//img.src="/myHelloWeb/servlet/ImageServlet";
img.src="/myHelloWeb/servlet/ImageServlet?"+time;
//?号后面的东西是通过get方式传递的
} </script>
</head> <body>
这是我的手动主页!
<br/>
<img id="servletImg" src="/myHelloWeb/servlet/ImageServlet" /><a href="javascript:changImg()">看不清</a>
</body>
</html>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>cn.hncu.img.ImageServlet</servlet-class>
</servlet> <servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/servlet/ImageServlet</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

ImageServlet.java

package cn.hncu.img;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Random; import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class ImageServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doPost(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//告诉客户端,输出的格式
response.setContentType("image/jpeg"); int width = 80;
int height = 40;
int lines = 10;
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics g = img.getGraphics(); //设置背景色
g.setColor(Color.WHITE);
g.fillRect(0, 0, width, height); //设置字体
g.setFont(new Font("宋体", Font.BOLD, 20)); //随机数字
Random r = new Random(new Date().getTime());
for(int i=0;i<4;i++){
int a = r.nextInt(10);
int y = 10+r.nextInt(20);//10~30范围内的一个整数,作为y坐标 Color c = new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255));
g.setColor(c); g.drawString(""+a, 5+i*width/4, y);
} //干扰线
for(int i=0;i<lines;i++){
Color c = new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255));
g.setColor(c);
g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r.nextInt(height));
} g.dispose();//类似于流中的close()带动flush()---把数据刷到img对象当中 ImageIO.write(img, "JPG", response.getOutputStream());
} }

演示结果:

下面这个是在index.jsp中:

如果是用这句:

img.src=”/myHelloWeb/servlet/ImageServlet”;

大家可以看看响应头:



再看看用这句的响应头:

img.src=”/myHelloWeb/servlet/ImageServlet?”+time;

多了个Date响应!

因为时间一直在变,所以每次点看不清,都会再向服务器请求一次,而不会因为浏览器的缓存,而不去请求了。

验证码就先到这里结束啦。

Web---图片验证码生成教程详解-从简单到复杂-从本地到前后台的更多相关文章

  1. SAE上传web应用(包括使用数据库)教程详解及问题解惑

    转自:http://blog.csdn.net/baiyuliang2013/article/details/24725995 SAE上传web应用(包括使用数据库)教程详解及问题解惑: 最近由于工作 ...

  2. webpack安装配置使用教程详解

    webpack安装配置使用教程详解 www.111cn.net 更新:2015-09-01 编辑:swteen 来源:转载 本文章来为各位详细的介绍一下关于webpack安装配置使用教程吧,这篇文章对 ...

  3. 史上最全的maven pom.xml文件教程详解

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...

  4. Android图片缓存之Bitmap详解

    前言: 最近准备研究一下图片缓存框架,基于这个想法觉得还是先了解有关图片缓存的基础知识,今天重点学习一下Bitmap.BitmapFactory这两个类. 图片缓存相关博客地址: Android图片缓 ...

  5. 开发工具类API调用的代码示例合集:六位图片验证码生成、四位图片验证码生成、简单验证码识别等

    以下示例代码适用于 www.apishop.net 网站下的API,使用本文提及的接口调用代码示例前,您需要先申请相应的API服务. 六位图片验证码生成:包括纯数字.小写字母.大写字母.大小写混合.数 ...

  6. Webstorm使用教程详解

    Webstorm使用教程详解 Webstorm垂直分栏.左右分栏 Webstorm 主题.背景.颜色等设置的导入导出   使用WebStorm开发web前端 网页中文乱码问题的解决方案 Webstor ...

  7. web页面 验证码 生成

    web页面 验证码 生成 kaptcha 是一个非常实用的验证码生成工具.有了它,你可以生成各种样式的验证码,因为它是可配置的.kaptcha工作的原理是调用 com.google.code.kapt ...

  8. Pycharm新手使用教程(详解)

    Pycharm新手使用教程(详解) [注]: 如果想要下载Pycharm工具,直接去<开发工具>中进行下载. 简介 Jetbrains家族和Pycharm版本划分: pycharm是Jet ...

  9. windows上安装Anaconda和python的教程详解

    一提到数字图像处理编程,可能大多数人就会想到matlab,但matlab也有自身的缺点: 1.不开源,价格贵 2.软件容量大.一般3G以上,高版本甚至达5G以上. 3.只能做研究,不易转化成软件. 因 ...

随机推荐

  1. linux下shell编程示例-获取进程id

    今天初步学习了一下linux下的shell编程,简单记录一下测试用例 1.编辑shell脚本文件如下: #!/bin/bashecho "hello bash linux"echo ...

  2. 《精通CSS-高级Web标准解决方案》阅读计划

    第一周     第1章 基础知识 1 第2章 为样式找到应用目标 1 第3章 可视化格式模型 1 第4章 背景图像效果 1       第二周     第5章 对链接应用样式 1 第6章 对列表应用样 ...

  3. php PHP_EOL 常量

    换行符 unix系列用 \n windows系列用 \r\n mac用 \r PHP中可以用PHP_EOL来替代,以提高代码的源代码级可移植性 <?php echo PHP_EOL; //win ...

  4. jquery ajax post, get, javascript ajax post, get 处理

    ajax 创建 XMLHttp 对象IE7 以上的版本都支持 XMLHttpRequestIE7 以下的用 ActiveXObject async:true,  // 当false 时,当执行完这个才 ...

  5. 怎么样调试正在运行的exe?

    最近在调虚幻的编辑器的时候遇到了一个问题. 调试模式运行UE4Editor.exe 实际上只是一个带参的命令行. 打开后,它又通过这个参数生成了一份详细配置,重新调用了自己.如图 这就悲剧了,断点都没 ...

  6. php文件上传大小限制设置

    配置选项说明: upload_max_filesize 所上传的文件的最大大小. post_max_size 设定 POST 数据所允许的最大大小. memory_limit 设定了一个脚本所能够申请 ...

  7. 【python之路7】python基本数据类型(一)

    一.运算符 1.算数运算符 +.-.*./.%(求余数).//(取整数部分) python2.x中,如果计算浮点数其中一个数字必须是浮点数否则按整数计算: 如python2.7中:print 9/2 ...

  8. 定位 - CoreLocation - 指南针

    #import "ViewController.h" #import <CoreLocation/CoreLocation.h> @interface ViewCont ...

  9. 两台主机打通ssh

    ssh打通基本概念:如果需要通过SSH进行远程登录,我们一般是需要手动输入密码,但如果将SSH之间的权限打通的话,就可以实现无密码登录.这对shell脚本的定时执行有很大的帮助. (一),生成秘钥,先 ...

  10. 分享七款视差滚动效果的jQuery 插件

    视差(Parallax)是指从不同的点看一个物体时形成的视觉差异,这个名词是源自希腊文的παράλλαξις (parallaxis),意思是”改变”.在网页设计中,视差滚动(Parallax Scr ...