学了好久的java, 但是没有思考过用它来画图,这几天公司有个需求,后台要画一个带二维码的合成图。我个人理解成3个图片的合成,一个是 背景图,一个是 带虚线边框的文案(根据入参变化),二维码(根据入参变化)。之前搞过一次背景图和二维码的合成,效果还是不错的。这次要加上文案,细细思考,似乎也不难。
思考过后,计划采用 Graphics2D 画笔 画文案。
思路如下:
Graphics2D drawString 画 字符串
Graphics2D setBackground(Color.WHITE) + clearRect(0, 0, 120, 60) --> 画背景图(大小充满整张图片)
Graphics2D setStroke 设定画笔的粗细以及颜色,线条的特征,比如实线、虚线
Graphics2D drawRect 画 矩形,以整张图片的大小为数据
实际操作过程中,遇到了以下几个问题:
1.整张图片的大小:以实际需要的尺寸来定,大小 通过生成 BufferedImage bimg = new BufferedImage(120, 60,BufferedImage.TYPE_INT_RGB); 来生成,当然我这里的死的,参数都可以是动态的。
2.背景图变黑了: 实践说明 setBackground(Color.WHITE) + clearRect(0, 0, 120, 60) 才能画上背景图,否则一直都黑。
3.虚线边框(红色):
a. 研究了BasicStroke ,发现可以满足需求。BasicStroke(float width, int cap, int join, float miterlimit,float dash[], float dash_phase)
width: 线条的宽度
cap:线条充满的幅度 CAP_BUTT, CAP_ROUND or CAP_SQUARE
jion:线端交接的形状:比如圆角 JOIN_ROUND、三角 JOIN_MITER、平滑 JOIN_BEVEL
miterlimit: 配合JOIN_MITER使用,防止三角边的长度过长
dash[]: 虚线的定义:“线+缺口+线+缺口+线+缺口… 比如: new float[] { 10, 5 }
dash_phase 线条的偏移:与虚线有关,按照api定义,比如虚线 { 10, 5 }, 第一根线长 10,如何dash_phase为5,那么,整条虚线向后迁移 5 ,也就是说 第一根线长度只有5,其后的线长基本是10,缺口都是5.
更详细的 BasicStroke 定义,可以参考 http://momsbaby1986.iteye.com/blog/1462901。
b. Graphics2D.setColor(Color.RED)--设定线条的颜色
4.文案:drawString 不能换行,不认得\r\n,所以需要自己定义换行。这个可以找网上资料,比较多。大约都是 解析 字符串,遇到 \n,更改垂直坐标、水平坐标。但是我这里只有两行,简约几个字。所以简单的两个
drawString 了事。
5.图片生产: 老方法:ImageIO.write(bimg, "JPG", new FileOutputStream("d:\\picture\\cavas.jpg"));
下面是代码,可以参考下,按照自己的需求改造。
public class TestRectant {
public static void main(String[] args) throws Exception {
BufferedImage bimg = new BufferedImage(120, 60,
BufferedImage.TYPE_INT_RGB);
// 得到Graphics2D 对象
Graphics2D g2d = (Graphics2D) bimg.getGraphics();
// 设置颜色和画笔粗细
g2d.setBackground(Color.WHITE);
g2d.setColor(Color.RED);
// g2d.setStroke(new BasicStroke(3));
BasicStroke stroke = new BasicStroke(2.5f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_ROUND, 3.5f, new float[] { 10, 5 }, 0f);
g2d.setStroke(stroke);
g2d.clearRect(0, 0, 120, 60);// 通过使用当前绘图表面的背景色进行填充来清除指定的矩形。
g2d.drawRect(0, 0, 120, 60);
// 绘制图案或文字
g2d.drawString("文本你好", 20, 30);
g2d.drawString("文本你好", 20, 50);
// 保存新图片
ImageIO.write(bimg, "JPG", new FileOutputStream(
"d:\\picture\\cavas.jpg"));
}
}
效果图: