那天突然看到了一些中文的验证码,所以想写一些东西,帮助大家了解一下在jsp页面中如何生成自己的验证码
一、简介
在 Java 2 平台之前,语言中的图形功能相当简单,仅限于单像素厚度的实线;少数几个几何图形(如椭圆、弧和多边形);和基本的画图功能。随着 Java 2D API(它包含一个真正的功能集)的出现,所有的一切都改变了。
Java 2D API是JFC (Java Fundation Classes)的一员,JFC 指的是包含在 Java 2 平台内的一整套图形和用户界面技术,包括 AWT 和 Swing 等。Java 2D加强了传统AWT( Abstract Windowing Toolkit )的描绘功能。在 JDK1.2中已经支援 Java 2D 的使用。透过Java 2D API ,Programmer 可以轻松地描绘出任意的几何图形、运用不同的填色效果、对图形做旋转( rotate)、缩放( scale)、扭曲( shear)等。当然,2D API还有许多增强AWT能力的部分,像是处理影像档案可以有不同的滤镜(filter)效果、对於任意的几何图形亦能做碰撞侦测(hit detection)、图形重叠混色计算(composite)等功能。后面将会对这些技术做概略性地介绍。
这个 API 的核心是由 java.awt.Graphics2D 类提供的,该类是 java.awt.Graphics 的一个子类。API 的其它部分由 java.awt 层次结构中的其它包提供,包括 java.awt.color 、 java.awt.font 和 java.awt.geom 。
Java 2D API 的文本功能也相当强大。它们包括:
java.awt包含了一些新增的2D API 类别(classes)和界面(interfaces )。其中 Graphics2D继承自 java.awt.Graphics ,是描绘2D图形的物件(object)。如同前版本的JDK所使用的绘图模式一样,当有物件要被描绘时,paint或是update method会自动根据适当的 Graphics Context 来做绘图的工作。所谓的Graphics Context是与Graphics Object相关状态属性(state attribute)的集合。在Graphics2D中新增了许多状态属性,像是Stroke、 Paint、Clip、 Transform等。
2.2 java.awt.geom 包
java.awt.geom 包提供一些有关二维几何的类,如 Arc2D 、 Line2D 、 Rectangle2D 、 Ellipse2D 和 CubicCurve2D 。
这些类允许各种几何图形建立在双精度或浮点精度的坐标系上。例如, newEllipse2D.Float(x,y,w,h) 将在 (x,y) 点上构造一个以宽为 w、高为 h 的矩形为边界的椭圆,其中 x、y、w和 h都为浮点值。
在这个包里还有 AffineTransform 类,它是组成 2D API 的核心元素。仿射转换指的是平行线在转换后还保持平行。这种类型的转换示例包括如下的操作:平移、旋转、缩放、剪切或者这些操作的组合。每一个转换都可以 用一个 3x3 的矩阵来表示,该矩阵规定转换的源点和目标点之间的映射。
AffineTransform 类的实例可以直接从一个浮点值的矩阵中创建,尽管通常情况下是通过规定一个或多个平移、旋转、缩放或剪切操作来创建。多数情况下是使用双精度值,并且角度是用弧度来度量的(而不是 Arc2D 类中使用的度)。
java.awt.geom 则包含可以勾勒任何形状的 GeneralPath类别。它可以由许多不同种类的subpath构成,像是lines和 quadratic curves 等。为了兼顾方便性,此package中更定义了许多基本几何图形,包括Arc2D 、CubicCurve2D、 Line2D等。这些类别都有两种型态,分别是Float precision与Double precision。此外,还有一种特别的图形类别:Area,它支援Constructive Area Geometry( CGA)。CGA是对既有图形物件做布尔运算(Boolean Operation)而产生新图形物件的过程。Areas支援联集( union)、交集( intersection)、差集(subtraction )、Exclusive OR (XOR)等布尔运算。最後, AffineTransform 类别则提供图形物件做Scale、Shear 、Rotate等座标上的转换。
2.3 java.awt.font 包
java.awt.font 中定义了 TextLayout类别,负责建构text shape、执行适当的 text operations,如碰撞侦测与打光 (highlighting)等,以及决定text的适当位置与顺序。
Package java.awt.color定义了class ColorSpace。此class提供Programmer转换色盘的method。
2.6 java.awt.print 包
Java Printing API提供Programmer 列印AWT和Java 2D graphics(composit ed graphics和 images)的method。并可让User设定 print的属性,如双面列印等。
2.7 java.awt.Graphics2D 类
这个类是 java.awt.Graphics (该类在 Java 2 发行前就提供图形功能)的一个子类。这样安排的原因是:向后兼容。组件的着色还是通过调用它们的 paint() 方法,它使用一个 Graphics 对象。
尽管在语言的当前版本中,这个对象真是一个 Graphics2D 对象。这意味着, paint() 方法可以将 Graphics 对象作为一个 Graphics 对象使用(使用旧的画图方法),或者将其强制转换成 Graphics2D 对象。如果使用第二种选择,就可以使用 2D API 的所有附加功能。
绘图的第一个步骤是产生 Graphics2D Object 。 接著是设定你所 要的状态属性。例如你想要对一物件做渐层式的填色,可以设定属性 Paint为 GradientPaint。最後再呼叫 Graphics2D所提供的redering method ,fill或是draw,完成整个绘图的程序。以下即是此基本步骤的范例程代码:
import java.awt.*; import java.awt.geom.*; public void paint(Graphics g) { Ellipse2D.Float shape; GradientPaint gp; // create a Graphics2D Graphics2D g2 = (Graphics2D) g ; // create a Ellipse2D (x,y,w,h) shape = new Ellipse2D.Float (200,200,60,60); // create a Cyclic GradientPaint // (x1,y1,color1,x2,y2,color2, boolean cyclic) gp = new GradientPaint (180,190,Color.yellow,220,210,Color.red,true); g2.setPaint(gp); g2.fill(shape); }
3.2 如何画线
在jdk尚未支援 2D图形之前, Programmer只可以画出直的、相同粗细的线条。现在,我们就教您如何透过2D API绘出不同粗细的线条及圆滑的曲线。在package java.awt.geom中提供了Line2D、 QuadCurve2D及 CubicCurve2D等 classes,让 Programmer轻松地绘出想要的线条。范例代码如下所示:
import java.awt.geom.*; … Line2D.Float line; CubicCurve2D.Float cubic; // create a Line2D line = new Line2D.Float(20,390,200,390); // create a CubicCurve2D,比直线多了两个控制点 cubic = new CubicCurve2D.Float(70,100,120,50,170,270,220,100); // 设定描绘的粗细 g2. setStroke(new BasicStroke(2.0f)); g2.setColor(Color.blue); g2.draw(line); line = new Line2D.Float(30,400,250,400); // 设定描绘的粗细 g2. setStroke(new BasicStroke(5.0f)); g2.draw(line);
3.3显示字串
透过Java 2D, Programmer可以显示更细致的文字。如范例代码的效果:显示出外边为淡蓝色的字串 " Font Test "。
import java.awt.font.*; … Shape sha; FontRenderContext frc =g2.getFontRenderContext(); TextLayout tl = new TextLayout("Font Test",new Font("Modern", Font.BOLD+Font.ITALIC,20),frc); sha=tl.getOutline(AffineTransform.getTranslateInstance(50,380)); g2.setColor(Color.blue); g2.setStroke(new BasicStroke(2.0f)); g2.draw(sha); g2.setColor(Color.white); g2.fill(sha);
3.4图档处理
之前,若希望图形有滤镜的效果,必须透过可以处理图形的绘图软体来帮忙。在2D API中则提供了一些简单的method,使得 Programmer可以直接用程式码来对图形作滤镜效果的控制。下面即介绍其中一种效果。范例代码如下所示:
float[] elements = {0.0f, -1.0f, 0.0f,-1.0f, 4.f, -1.0f,0.0f, -1.0f, 0.0f}; Image img = Toolkit.getDefaultToolkit().getImage("boat.gif"); int w = img.getWidth(this); int h = img.getHeight(this); BufferedImage bi = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB); Graphics2D big = bi.createGraphics(); big.drawImage(img,0,0,this); BufferedImageOp biop = null; AffineTransform at = new AffineTransform(); BufferedImage bimg = new BufferedImage(img.getWidth(this),img.getHeight(this), BufferedImage.TYPE_INT_RGB); Kernel kernel = new Kernel(3,3,elements); ConvolveOp cop = new ConvolveOp(kernel,ConvolveOp.EDGE_NO_OP,null); cop.filter(bi,bimg); biop = newAffineTransformOp(at,AffineTransformOp.TYPE_NEAREST_NEIGHBOR); g2 = (Graphics2D)this.getGraphics(); g2.drawImage(bimg,biop,0,0);
清单 1 包含一个使用部分 Java 2D 方法的基本示例的代码,加上几个其它的方法。这是一个完整的程序,但只是接触了 2D API 所提供的功能的皮毛。
清单 1. 一个简单的 Java 2D 示例
import java.awt.*; import java.awt.geom.*; public class J2D extends Frame { public static void main(String args[]) { new J2D(); } public J2D() { setSize(220,180); setVisible(true); } public void paint(Graphics g) { // 获得一个Graphics2D对象 Graphics2D g2 = (Graphics2D)g; // 设置绘制质量 g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // 定义线性色度分级 GradientPaint gp = new GradientPaint(0, 60, Color.red, 0, 120, Color.yellow); Ellipse2D r = new Ellipse2D.Float(30, 60, 160, 60); g2.setPaint(gp); g2.fill(r); // 设置旋转 g2.transform(AffineTransform.getRotateInstance(Math.PI/8)); g2.setFont(new Font("Serif", Font.BOLD, 85)); g2.setPaint(Color.blue); // 设置透明度 g2.setComposite(AlphaComposite.getInstance( AlphaComposite.SRC_OVER, 0.5f)); g2.drawString("J2D",50,70); }
本文链接:http://www.snowdi.com/444.html → 转载请注明文章出自雪頔网