Javaweb笔记(一)java代码生成图片总结

使用Java代码生成一张图片中使用到的类有:BufferedImage,Graphics,ImageIO;

  • BufferedImage:图片缓冲区,也就是绘制图片的画布
  • Graphics:绘制图片内容的画笔(设置画笔的颜色,绘制的内容等操作)
  • ImageIO:由于以上的操作都是在声明的缓冲区进行操作的,现将绘制完成的图片保存到本地的操作类

example:绘制一张图片,背景为白色,字体为蓝色,内容为“hello image”的图片

编写步骤如下:
  • 1.声明初始化画布(图片的缓冲区)
    BufferedImage bufferedImage = new BufferedImage(70, 35,BufferedImage.TYPE_INT_RGB);
  • 2.通过画布获取画笔
    Graphics paint = bufferedImage.getGraphics();
  • 3.设置画笔颜色
    paint.setColor(Color.WHITE);
  • 4.填充图片背景色为白色
    paint.fillRect(0, 0, 70, 35);
  • 5.设置画笔的颜色为蓝色,为绘制图片内容作准备
    paint.setColor(Color.blue);
  • 6.使用画笔绘制显示的内容
    paint.drawString("hello image",5,15);
  • 7.绘制完成,则将现在缓冲区的图片样本保存在本地文件中
    ImageIO.write(bufferedImage, "jpeg", new FileOutputStream("/Users/wujinli/Desktop/java-draw.jpg"));
public class DrawImage {

    @Test
    public void drawImage() throws FileNotFoundException, IOException {
        // 获取图片的缓冲区,也就是所谓的画布
        BufferedImage bufferedImage = new BufferedImage(80, 35, BufferedImage.TYPE_INT_RGB);
        //获取画笔,画笔用于在画布上进行绘制
        Graphics paint = bufferedImage.getGraphics();
        //设置画笔的颜色
        paint.setColor(Color.WHITE);
        //绘制画布的背景色
        paint.fillRect(0, 0, 80, 35);
        //设置画笔的颜色
        paint.setColor(Color.blue);
        //绘制显示的具体内容
        paint.drawString("hello image",5,20);
        //绘制完成保存文件
        ImageIO.write(bufferedImage, "jpeg", new FileOutputStream("/Users/wujinli/Desktop/java-draw.jpg"));
    }

}

这样可以生成一张带有hello image字样的图片了;

在实际开发中,我们在登陆或者注册页面会涉及到图形验证码的场景,线收集一个生成图片验证码的工具类:

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" };
    // 定义有那些验证码的随机字符
    private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKLMNOPQRSTUVWXYZ";
    // 生成背景色
    private Color bgColor = new Color(250, 250, 250);
    // 用于gettext 方法 获得生成的验证码文本
    private String text;
    // 生成随机颜色
    private Color randomColor() {
        int red = r.nextInt(150);
        int green = r.nextInt(150);
        int blue = r.nextInt(150);
        return new Color(red, green, blue);
    }
    // 生成随机字体
    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);
    }
    // 画干扰线
    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的长度内的随机数 并使用charAt 取得随机数位置上的codes中的字符
    private char randomChar() {
        int index = r.nextInt(codes.length());
        return codes.charAt(index);
    }
    // 创建一张验证码的图片
    public BufferedImage createImage() {
        BufferedImage image = new BufferedImage(w, h,
                BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = (Graphics2D) image.getGraphics();
        StringBuilder sb = new StringBuilder();
        // 向图中画四个字符
        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;
    }
    // 得到验证码的文本 后面是用来和用户输入的验证码 检测用
    public String getText() {
        return text;
    }
    // 定义输出的对象和输出的方向
    public static void output(BufferedImage bi, OutputStream fos)
            throws FileNotFoundException, IOException {
        ImageIO.write(bi, "JPEG", fos);
    }
}

java测试代码:

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中可以实现生成图片的功能

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文件的实现方式

<img src="/项目名称/VerifyCodeServlet">

现在我们实现了在页面上展示校验码图片,但是在实际开发中呢,我们有再换一张的需求;所以需要动态的去请求验证码展示的图片,则实现过程如下:

<img id="imageverify"
                src="/firstweb/VerifyCodeServlet"> <a
                href="javascript:_changeImage()">换一张</a>


<script type="text/javascript">
    function _changeImage() {
        /**
        1.获取图片元素
        2.设置资源
        */
        var imageverify = document.getElementById("imageverify");
        imageverify.src = "/firstweb/VerifyCodeServlet?a="+new Date().getTime();
    }
</script>

这样就可以实现换一张的操作,需要解释的是imageverify.src = "/firstweb/VerifyCodeServlet?time="+new Date().getTime()的编写是因为浏览器会缓存之前请求的图片,当请求同样的请求是,他会先去去缓存寻找,这样为了避免点击没有效果的bug,现在我们可以在请求路径后加上日期时间,这样在请求中服务器会以为每次请求都是新的请求操作,这样就不会去缓存中去寻找!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,142评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,298评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,068评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,081评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,099评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,071评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,990评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,832评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,274评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,488评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,649评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,378评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,979评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,625评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,643评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,545评论 2 352

推荐阅读更多精彩内容