篇十四:图片验证码
一、图形验证码代码
package com.guduo.common.utils; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.Random; import javax.imageio.ImageIO; public class CopyOfValidateCode { // 图片的宽度。 private int width = 160; // 图片的高度。 private int height = 40; // 验证码字符个数 private int codeCount = 5; // 验证码干扰线数 private int lineCount = 150; // 验证码 private static String code = null; // 验证码图片Buffer private BufferedImage buffImg=null; //验证码字符来源 private char[] codeSequence = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J','K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W','X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9' }; /** * 构造函数--按照初始化的配置 */ public CopyOfValidateCode() { this.createCode(); } /** * 构造函数--指定宽、高 * @param width 图片宽 * @param height 图片高 */ public CopyOfValidateCode(int width,int height) { this.width=width; this.height=height; this.createCode(); } /** * 构造函数--指定宽、高、字符数、干扰线条数 * @param width 图片宽 * @param height 图片高 * @param codeCount 字符个数 * @param lineCount 干扰线条数 */ public CopyOfValidateCode(int width,int height,int codeCount,int lineCount) { this.width=width; this.height=height; this.codeCount=codeCount; this.lineCount=lineCount; this.createCode(); } /** * 设置图片属性 */ public void createCode() { int x = 0,fontHeight=0,codeY=0; int red = 0, green = 0, blue = 0; x = width / (codeCount +2);//每个字符的宽度 fontHeight = height - 2;//字体的高度 codeY = height - 4; // 图像buffer buffImg = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB); Graphics2D g = buffImg.createGraphics(); // 生成随机数 Random random = new Random(); // 将图像填充为白色 g.setColor(Color.WHITE); g.fillRect(0, 0, width, height); // 创建字体 Font font = new Font("Fixedsys", Font.PLAIN, fontHeight); g.setFont(font); for (int i = 0; i < lineCount; i++) { int xs = random.nextInt(width); int ys = random.nextInt(height); int xe = xs+random.nextInt(width/8); int ye = ys+random.nextInt(height/8); red = random.nextInt(255); green = random.nextInt(255); blue = random.nextInt(255); g.setColor(new Color(red, green, blue)); g.drawLine(xs, ys, xe, ye); } // randomCode记录随机产生的验证码 StringBuffer randomCode = new StringBuffer(); // 随机产生codeCount个字符的验证码。 for (int i = 0; i < codeCount; i++) { String strRand = String.valueOf(codeSequence[random.nextInt(codeSequence.length)]); // 产生随机的颜色值,让输出的每个字符的颜色值都将不同。 red = random.nextInt(255); green = random.nextInt(255); blue = random.nextInt(255); g.setColor(new Color(red, green, blue)); g.drawString(strRand, (i + 1) * x, codeY); // 将产生的四个随机数组合在一起。 randomCode.append(strRand); } code = randomCode.toString(); } /** * 生成图片,上传 * @param buffImg * @return * @throws IOException */ public String write(BufferedImage buffImg) throws IOException { try { ByteArrayOutputStream sos = new ByteArrayOutputStream(); ImageIO.write(buffImg, "png", sos); InputStream is = new ByteArrayInputStream(sos.toByteArray()); sos.close(); byte[] data = new byte[is.available()]; is.read(data); is.close(); String image = Base64Utils.encode(data); return image; } catch (Exception e) { e.printStackTrace(); } return null; } public BufferedImage getBuffImg() { return buffImg; } public static String getCode() { return code; } public static void main(String[] args) { CopyOfValidateCode vCode = new CopyOfValidateCode(100,30,4,4); System.out.println(vCode.getBuffImg()); System.out.println(vCode.getCode()); try { System.out.println(new CopyOfValidateCode().write(vCode.getBuffImg())); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
二、步骤解析
1、BufferedImage类
Image是一个抽象列,BufferedImage是Image的实现。BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便的操作这个图片,通常用来做图片修改操作如大小变换、图片变灰、设置图片透明或不透明等
BufferedImage bufferedImage = ImageIO.read(new FileInputStream(filePath)); //读取一幅图像到图像缓冲区
//初始化对象,指定宽度、高度、图片类型
BufferedImage bufferImage = new BufferedImage(BUFFER_IMAGE_WIDTH, BUFFER_IMAGE_HEIGHT, BufferedImage.TYPE_INT_RGB);
//初始化对象后,获取Graphics
Graphics2D g = bufferImage.createGraphics();
重点:1、初始化时指定图片类型
2、通过BufferedImage创建Graphics2D对象,用于画图
字段摘要:图片类型 | |
---|---|
static int |
TYPE_3BYTE_BGR 表示一个具有 8 位 RGB 颜色分量的图像,对应于 Windows 风格的 BGR 颜色模型,具有用 3 字节存储的 Blue、Green 和 Red 三种颜色。 |
static int |
TYPE_4BYTE_ABGR 表示一个具有 8 位 RGBA 颜色分量的图像,具有用 3 字节存储的 Blue、Green 和 Red 颜色以及 1 字节的 alpha。 |
static int |
TYPE_4BYTE_ABGR_PRE 表示一个具有 8 位 RGBA 颜色分量的图像,具有用 3 字节存储的 Blue、Green 和 Red 颜色以及 1 字节的 alpha。 |
static int |
TYPE_BYTE_BINARY 表示一个不透明的以字节打包的 1、2 或 4 位图像。 |
static int |
TYPE_BYTE_GRAY 表示无符号 byte 灰度级图像(无索引)。 |
static int |
TYPE_BYTE_INDEXED 表示带索引的字节图像。 |
static int |
TYPE_CUSTOM 没有识别出图像类型,因此它必定是一个自定义图像。 |
static int |
TYPE_INT_ARGB 表示一个图像,该图像具有打包成整数像素的 8 位 RGBA 颜色分量。 |
static int |
TYPE_INT_ARGB_PRE 表示一个图像,该图像具有打包成整数像素的 8 位 RGBA 颜色分量。 |
static int |
TYPE_INT_BGR 表示一个具有 8 位 RGB 颜色分量的图像,对应于 Windows 或 Solaris 风格的 BGR 颜色模型,具有打包为整数像素的 Blue、Green 和 Red 三种颜色。 |
static int |
TYPE_INT_RGB 表示一个图像,该图像具有打包成整数像素的 8 位 RGB 颜色分量。 |
static int |
TYPE_USHORT_555_RGB 表示一个具有 5-5-5 RGB 颜色分量(5 位 red、5 位 green、5 位 blue)的图像,不带 alpha。 |
static int |
TYPE_USHORT_565_RGB 表示一个具有 5-6-5 RGB 颜色分量(5 位 red、6 位 green、5 位 blue)的图像,不带 alpha。 |
static int |
TYPE_USHORT_GRAY 表示一个无符号 short 灰度级图像(无索引)。 |
方法摘要 | |
---|---|
void |
addTileObserver(TileObserver to) 添加一个 tile observer。 |
void |
coerceData(boolean isAlphaPremultiplied) 强制该数据与 isAlphaPremultiplied 变量中指定的状态相匹配。 |
WritableRaster |
copyData(WritableRaster outRaster) 计算 BufferedImage 的一个任意的矩形区域,并将其复制到指定的 WritableRaster 。 |
Graphics2D |
createGraphics() 创建一个 Graphics2D ,可以将它绘制到此 BufferedImage 中。 |
void |
flush() 刷新所有正用于缓存优化信息的资源。 |
WritableRaster |
getAlphaRaster() 返回一个 WritableRaster ,它使用支持单独空间 alpha 通道的 ColorModel 对象(比如 ComponentColorModel 和 DirectColorModel )表示 BufferedImage 对象的 alpha 通道。 |
ImageCapabilities |
getCapabilities(GraphicsConfiguration gc) 重写 Image.getCapabilities(gc) 以获得其 surfaceManager 的能力。 |
ColorModel |
getColorModel() 返回 ColorModel 。 |
Raster |
getData() 作为一个大 tile 返回图像。 |
Raster |
getData(Rectangle rect) 计算并返回 BufferedImage 的一个任意区域。 |
Graphics |
getGraphics() 此方法返回 Graphics2D ,但此处是出于向后兼容性的考虑。 |
int |
getHeight() 返回 BufferedImage 的高度。 |
int |
getHeight(ImageObserver observer) 返回 BufferedImage 的高度。 |
int |
getMinTileX() 返回 x 方向的最小 tile 索引。 |
int |
getMinTileY() 返回 y 方向的最小 tile 索引。 |
int |
getMinX() 返回此 BufferedImage 的最小 x 坐标。 |
int |
getMinY() 返回此 BufferedImage 的最小 y 坐标。 |
int |
getNumXTiles() 返回 x 方向的 tile 数。 |
int |
getNumYTiles() 返回 y 方向的 tile 数。 |
Object |
getProperty(String name) 按名称返回图像的属性。 |
Object |
getProperty(String name, ImageObserver observer) 按名称返回图像的属性。 |
String[] |
getPropertyNames() 返回由 getProperty(String) 识别的名称数组;如果没有识别出属性名,则返回 null 。 |
WritableRaster |
getRaster() 返回 WritableRaster 。 |
int |
getRGB(int x, int y) 返回默认 RGB 颜色模型 (TYPE_INT_ARGB) 和默认 sRGB 颜色空间中的整数像素。 |
int[] |
getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) 从图像数据的某一部分返回默认 RGB 颜色模型 (TYPE_INT_ARGB) 和默认 sRGB 颜色空间中整数像素的数组。 |
SampleModel |
getSampleModel() 返回与此 BufferedImage 相关的 SampleModel 。 |
ImageProducer |
getSource() 返回产生该图像像素的对象。 |
Vector<RenderedImage> |
getSources() 返回 RenderedImage 对象的 Vector ,该对象是此 BufferedImage 的图像数据的直接来源,而不是这些直接来源的来源。 |
BufferedImage |
getSubimage(int x, int y, int w, int h) 返回由指定矩形区域定义的子图像。 |
Raster |
getTile(int tileX, int tileY) 返回 tile ( tileX , tileY )。 |
int |
getTileGridXOffset() 返回 tile 网格相对于原点(例如,tile (0, 0) 位置的 x 坐标)的 x 偏移量。 |
int |
getTileGridYOffset() 返回 tile 网格相对于原点(例如,tile (0, 0) 位置的 y 坐标)的 y 偏移量。 |
int |
getTileHeight() 返回 tile 高度(以像素为单位)。 |
int |
getTileWidth() 返回 tile 宽度(以像素为单位)。 |
int |
getTransparency() 返回透明度。 |
int |
getType() 返回图像类型。 |
int |
getWidth() 返回 BufferedImage 的宽度。 |
int |
getWidth(ImageObserver observer) 返回 BufferedImage 的宽度。 |
WritableRaster |
getWritableTile(int tileX, int tileY) 为写入签出一个 tile。 |
Point[] |
getWritableTileIndices() 返回 Point 对象的数组,它指示为写入签出了哪些 tile。 |
boolean |
hasTileWriters() 返回是否有为写入而签出的 tile。 |
boolean |
isAlphaPremultiplied() 返回是否已预乘以 alpha。 |
boolean |
isTileWritable(int tileX, int tileY) 返回当前是否正在为写入签出 tile。 |
void |
releaseWritableTile(int tileX, int tileY) 放弃写入一个 tile 的权限。 |
void |
removeTileObserver(TileObserver to) 移除一个 tile observer。 |
void |
setData(Raster r) 将图像的矩形区域设置为指定 Raster r 的内容,假定该区域与 BufferedImage 处于相同的坐标空间。 |
void |
setRGB(int x, int y, int rgb) 将此 BufferedImage 中的像素设置为指定的 RGB 值。 |
void |
setRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize) 将默认 RGB 颜色模型 (TYPE_INT_ARGB) 和默认 sRGB 颜色空间中的整数像素数组设置为图像数据的一部分。 |
String |
toString() 返回此 BufferedImage 对象及其值的 String 表示形式。 |
2、Graphics2D类
Graphics2D绘画:
g.fillRect(0, 0, width, height):填充指定区域
g.drawString(String str, float x, float y)
字符串
方法摘要 | |
---|---|
abstract void |
addRenderingHints(Map<?,?> hints) 为呈现算法设置任意数量的首选项值。 |
abstract void |
clip(Shape s) 将当前 Clip 与指定 Shape 的内部区域相交,并将 Clip 设置为所得的交集。 |
abstract void |
draw(Shape s) 使用当前 Graphics2D 上下文的设置勾画 Shape 的轮廓。 |
void |
draw3DRect(int x, int y, int width, int height, boolean raised) 绘制指定矩形的 3-D 高亮显示边框。 |
abstract void |
drawGlyphVector(GlyphVector g, float x, float y) 使用 Graphics2D 上下文的呈现属性,呈现指定 GlyphVector 的文本。 |
abstract void |
drawImage(BufferedImage img, BufferedImageOp op, int x, int y) 呈现使用 BufferedImageOp 过滤的 BufferedImage 。 |
abstract boolean |
drawImage(Image img, AffineTransform xform, ImageObserver obs) 呈现一个图像,在绘制前进行从图像空间到用户空间的转换。 |
abstract void |
drawRenderableImage(RenderableImage img, AffineTransform xform) 呈现 RenderableImage,在绘制前进行从图像空间到用户空间的转换。 |
abstract void |
drawRenderedImage(RenderedImage img, AffineTransform xform) 呈现 RenderedImage,在绘制前进行从图像空间到用户空间的转换。 |
abstract void |
drawString(AttributedCharacterIterator iterator, float x, float y) 依照 TextAttribute 类的规范应用指定迭代器的属性,呈现指定迭代器的文本。 |
abstract void |
drawString(AttributedCharacterIterator iterator, int x, int y) 依照 TextAttribute 类的规范应用指定迭代器的属性,呈现指定迭代器的文本。 |
abstract void |
drawString(String str, float x, float y) 使用 Graphics2D 上下文中当前文本属性状态呈现由指定 String 指定的文本。 |
abstract void |
drawString(String str, int x, int y) 使用 Graphics2D 上下文中的当前文本属性状态呈现指定的 String 的文本。 |
abstract void |
fill(Shape s) 使用 Graphics2D 上下文的设置,填充 Shape 的内部区域。 |
void |
fill3DRect(int x, int y, int width, int height, boolean raised) 绘制一个用当前颜色填充的 3-D 高亮显示矩形。 |
abstract Color |
getBackground() 返回用于清除区域的背景色。 |
abstract Composite |
getComposite() 返回 Graphics2D 上下文中的当前 Composite |
abstract GraphicsConfiguration |
getDeviceConfiguration() 返回与此 Graphics2D 关联的设备配置。 |
abstract FontRenderContext |
getFontRenderContext() 获取此 Graphics2D 上下文中 Font 的呈现上下文。 |
abstract Paint |
getPaint() 返回 Graphics2D 上下文中的当前 Paint |
abstract Object |
getRenderingHint(RenderingHints.Key hintKey) 返回呈现算法的单个首选项的值。 |
abstract RenderingHints |
getRenderingHints() 获取呈现算法的首选项。 |
abstract Stroke |
getStroke() 返回 Graphics2D 上下文中的当前 Stroke |
abstract AffineTransform |
getTransform() 返回 Graphics2D 上下文中当前 Transform 的副本。 |
abstract boolean |
hit(Rectangle rect, Shape s, boolean onStroke) 检查指定的 Shape 是否与设备空间中的指定 Rectangle 相交。 |
abstract void |
rotate(double theta) 将当前的 Graphics2D Transform 与旋转转换连接。 |
abstract void |
rotate(double theta, double x, double y) 将当前的 Graphics2D Transform 与平移后的旋转转换连接。 |
abstract void |
scale(double sx, double sy) 将当前 Graphics2D Transform 与缩放转换连接。 |
abstract void |
setBackground(Color color) 设置 Graphics2D 上下文的背景色。 |
abstract void |
setComposite(Composite comp) 为 Graphics2D 上下文设置 Composite 。 |
abstract void |
setPaint(Paint paint) 为 Graphics2D 上下文设置 Paint 属性。 |
abstract void |
setRenderingHint(RenderingHints.Key hintKey, Object hintValue) 为呈现算法设置单个首选项的值。 |
abstract void |
setRenderingHints(Map<?,?> hints) 使用指定的 hints 替换用于所有呈现算法首选项的值。 |
abstract void |
setStroke(Stroke s) 为 Graphics2D 上下文设置 Stroke |
abstract void |
setTransform(AffineTransform Tx) 重写 Graphics2D 上下文中的 Transform。 |
abstract void |
shear(double shx, double shy) 将当前 Graphics2D Transform 与剪裁转换连接。 |
abstract void |
transform(AffineTransform Tx) 根据“最后指定首先应用”规则,使用此 Graphics2D 中的 Transform 组合 AffineTransform 对象。 |
abstract void |
translate(double tx, double ty) 将当前 Graphics2D Transform 与平移转换连接。 |
abstract void |
translate(int x, int y) 将 Graphics2D 上下文的原点平移到当前坐标系中的点 (x, y)。 |
3、Color类
Color类是用来封装颜色的,可以通过两种方式创建:1、Color预定义的颜色枚举;2、RGB三基色
//预定义的颜色枚举 g.setColor(Color.blue); //三基色,不指定透明度,红,绿,蓝,通过三种颜色的调整得到其他各种颜色,这三种基色的范围为0—255 g.setColor(new Color(255,254,253)); //三基色,不指定透明度,alpha分量为0时,表示完全透明,前三个分量不起作用,而介于0——255之间的值可以制造出颜色不同的层次效果 //(int red ,int green,int blue,int alpha) g.setColor(new Color(125,15,17,68));
4、Font类
设计字体显示效果 Font mf = new Font(String 字体,int 风格,int 字号);
字体:TimesRoman, Courier, Arial等
风格:三个常量 Font.PLAIN(普通样式常量), Font.BOLD(粗体), Font.ITALIC(斜体)
字号:字的大小(磅数)