篇十四:图片验证码

一、图形验证码代码

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 (tileXtileY)。
 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 上下文的原点平移到当前坐标系中的点 (xy)。

  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(斜体)
     字号:字的大小(磅数)

posted @ 2016-11-09 21:52  刘广平  阅读(1144)  评论(0)    收藏  举报