使用Java代碼生成一張圖片中使用到的類(lèi)有:BufferedImage俱萍,Graphics,ImageIO;
- BufferedImage:圖片緩沖區(qū)挽拂,也就是繪制圖片的畫(huà)布
- Graphics:繪制圖片內(nèi)容的畫(huà)筆(設(shè)置畫(huà)筆的顏色,繪制的內(nèi)容等操作)
- ImageIO:由于以上的操作都是在聲明的緩沖區(qū)進(jìn)行操作的骨饿,現(xiàn)將繪制完成的圖片保存到本地的操作類(lèi)
example:繪制一張圖片亏栈,背景為白色,字體為藍(lán)色宏赘,內(nèi)容為“hello image”的圖片
編寫(xiě)步驟如下:
- 1.聲明初始化畫(huà)布(圖片的緩沖區(qū))
BufferedImage bufferedImage = new BufferedImage(70, 35,BufferedImage.TYPE_INT_RGB); - 2.通過(guò)畫(huà)布獲取畫(huà)筆
Graphics paint = bufferedImage.getGraphics(); - 3.設(shè)置畫(huà)筆顏色
paint.setColor(Color.WHITE); - 4.填充圖片背景色為白色
paint.fillRect(0, 0, 70, 35); - 5.設(shè)置畫(huà)筆的顏色為藍(lán)色绒北,為繪制圖片內(nèi)容作準(zhǔn)備
paint.setColor(Color.blue); - 6.使用畫(huà)筆繪制顯示的內(nèi)容
paint.drawString("hello image",5,15); - 7.繪制完成,則將現(xiàn)在緩沖區(qū)的圖片樣本保存在本地文件中
ImageIO.write(bufferedImage, "jpeg", new FileOutputStream("/Users/wujinli/Desktop/java-draw.jpg"));
public class DrawImage {
@Test
public void drawImage() throws FileNotFoundException, IOException {
// 獲取圖片的緩沖區(qū)察署,也就是所謂的畫(huà)布
BufferedImage bufferedImage = new BufferedImage(80, 35, BufferedImage.TYPE_INT_RGB);
//獲取畫(huà)筆闷游,畫(huà)筆用于在畫(huà)布上進(jìn)行繪制
Graphics paint = bufferedImage.getGraphics();
//設(shè)置畫(huà)筆的顏色
paint.setColor(Color.WHITE);
//繪制畫(huà)布的背景色
paint.fillRect(0, 0, 80, 35);
//設(shè)置畫(huà)筆的顏色
paint.setColor(Color.blue);
//繪制顯示的具體內(nèi)容
paint.drawString("hello image",5,20);
//繪制完成保存文件
ImageIO.write(bufferedImage, "jpeg", new FileOutputStream("/Users/wujinli/Desktop/java-draw.jpg"));
}
}
這樣可以生成一張帶有hello image字樣的圖片了;
在實(shí)際開(kāi)發(fā)中贴汪,我們?cè)诘顷懟蛘咦?cè)頁(yè)面會(huì)涉及到圖形驗(yàn)證碼的場(chǎng)景脐往,線收集一個(gè)生成圖片驗(yàn)證碼的工具類(lèi):
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import javax.imageio.ImageIO;
public class VerifyCode {
private int w = 70;
private int h = 35;
private Random r = new Random();
// 定義有那些字體
private String[] fontNames = { "宋體", "華文楷體", "黑體", "微軟雅黑", "楷體_GB2312" };
// 定義有那些驗(yàn)證碼的隨機(jī)字符
private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
// 生成背景色
private Color bgColor = new Color(250, 250, 250);
// 用于gettext 方法 獲得生成的驗(yàn)證碼文本
private String text;
// 生成隨機(jī)顏色
private Color randomColor() {
int red = r.nextInt(150);
int green = r.nextInt(150);
int blue = r.nextInt(150);
return new Color(red, green, blue);
}
// 生成隨機(jī)字體
private Font randomFont() {
int index = r.nextInt(fontNames.length);
String fontName = fontNames[index];
int style = r.nextInt(4);
int size = r.nextInt(5) + 24;
return new Font(fontName, style, size);
}
// 畫(huà)干擾線
private void drawLine(BufferedImage image) {
int num = 3;
Graphics2D g2 = (Graphics2D) image.getGraphics();
for (int i = 0; i < num; i++) {
int x1 = r.nextInt(w);
int y1 = r.nextInt(h);
int x2 = r.nextInt(w);
int y2 = r.nextInt(h);
g2.setStroke(new BasicStroke(1.5F));// 不知道
g2.setColor(Color.blue);
g2.drawLine(x1, y1, x2, y2);
}
}
// 得到codes的長(zhǎng)度內(nèi)的隨機(jī)數(shù) 并使用charAt 取得隨機(jī)數(shù)位置上的codes中的字符
private char randomChar() {
int index = r.nextInt(codes.length());
return codes.charAt(index);
}
// 創(chuàng)建一張驗(yàn)證碼的圖片
public BufferedImage createImage() {
BufferedImage image = new BufferedImage(w, h,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = (Graphics2D) image.getGraphics();
StringBuilder sb = new StringBuilder();
// 向圖中畫(huà)四個(gè)字符
for (int i = 0; i < 4; i++) {
String s = randomChar() + "";
sb.append(s);
float x = i * 1.0F * w / 4;
g2.setFont(randomFont());
g2.setColor(randomColor());
g2.drawString(s, x, h - 5);
}
this.text = sb.toString();
drawLine(image);
// 返回圖片
return image;
}
// 得到驗(yàn)證碼的文本 后面是用來(lái)和用戶輸入的驗(yàn)證碼 檢測(cè)用
public String getText() {
return text;
}
// 定義輸出的對(duì)象和輸出的方向
public static void output(BufferedImage bi, OutputStream fos)
throws FileNotFoundException, IOException {
ImageIO.write(bi, "JPEG", fos);
}
}
java測(cè)試代碼:
public class test {
public static void main(String[] args) throws IOException {
VerifyCode code = new VerifyCode();
BufferedImage image = code.createImage();
ImageIO.write(image,"jpg",new File("/Users/wujinli/Desktop/java-draw.jpg"));
}
在servlet中可以實(shí)現(xiàn)生成圖片的功能
public class VerifyCodeServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
VerifyCode code = new VerifyCode();
BufferedImage image = code.createImage();
ImageIO.write(image,"jpg",response.getOutputStream());
}
圖片的顯示可以在html或者jsp文件的實(shí)現(xiàn)方式
<img src="/項(xiàng)目名稱/VerifyCodeServlet">
現(xiàn)在我們實(shí)現(xiàn)了在頁(yè)面上展示校驗(yàn)碼圖片,但是在實(shí)際開(kāi)發(fā)中呢扳埂,我們有再換一張的需求业簿;所以需要?jiǎng)討B(tài)的去請(qǐng)求驗(yàn)證碼展示的圖片,則實(shí)現(xiàn)過(guò)程如下:
<img id="imageverify"
src="/firstweb/VerifyCodeServlet"> <a
href="javascript:_changeImage()">換一張</a>
<script type="text/javascript">
function _changeImage() {
/**
1.獲取圖片元素
2.設(shè)置資源
*/
var imageverify = document.getElementById("imageverify");
imageverify.src = "/firstweb/VerifyCodeServlet?a="+new Date().getTime();
}
</script>
這樣就可以實(shí)現(xiàn)換一張的操作阳懂,需要解釋的是imageverify.src = "/firstweb/VerifyCodeServlet?time="+new Date().getTime()的編寫(xiě)是因?yàn)闉g覽器會(huì)緩存之前請(qǐng)求的圖片梅尤,當(dāng)請(qǐng)求同樣的請(qǐng)求是柜思,他會(huì)先去去緩存尋找,這樣為了避免點(diǎn)擊沒(méi)有效果的bug巷燥,現(xiàn)在我們可以在請(qǐng)求路徑后加上日期時(shí)間赡盘,這樣在請(qǐng)求中服務(wù)器會(huì)以為每次請(qǐng)求都是新的請(qǐng)求操作,這樣就不會(huì)去緩存中去尋找缰揪!