在开发中,经常需要动态生成图片,比如验证码、二维码等,包括前一段时间很流行的小孩举牌牌的图片,在这种情况下,图片只能在服务器内存中动态生成并返回给用户,然后在浏览器中显示出来。
在 Java 中,java.awt 包提供了基本的绘制图像的能力,我们可以在内存中绘制好需要的图形,然后编码成 jpeg 或其他图像格式,最后发送相应给浏览器。下面是整理的一些常用方法:
这种情况主要是基于底图绘制目标图的场景:
BufferedImage bi = ImageIO.read(new ByteArrayInputStream(pngBytes));
Graphics2D g = (Graphics2D) bi.getGraphics();
例如绘制的图片需要黑体,然而服务器又不能让我们随便安装字段时可以如下处理:
Font base = Font.createFont(Font.TRUETYPE_FONT, new ByteArrayInputStream(ttfBytes));
g.setFont(base.deriveFont(26.0f)); // 字体大小 26 号
字体颜色的表达方式有很多种,此处主要是如何将 css 的颜色方式直接转换成 java 中的对象, 颜色查找可以查阅 RGB 颜色参考
g.setColor(Color.decode("0Xe8bc7f"));
文字居中的问题主要是获取文字长度的问题,相关操作方式如下:
String s = "这是一个测试字符串!";
int width = g.getFontMetrics().stringWidth(s);
g.drawString(s, 375 - width / 2, 100);
BufferedImage cover = xxxxxx;
RenderingHints hints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHints(hints);
g.drawImage(cover, 0, 0, newWidth, newHeight, 0, 0, cover.getWidth(), cover.getHeight(), null);
图片裁切主要基于 g.clip(Shape shap) 接口,多次调用可以多次裁切,裁切圆形可以:
Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, 100, 100);
g.clip(shape);
裁切矩形可以:
Rectangle2D.Double shap = new Rectangle2D.Double(0, 0, 100, 100);
g.clip(shape);
绘制完成后就可以结束操作返回浏览器了:
g.dispose();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ImageIO.write(bi, "png", bos);