使用Graphics2D在图片上写字
首先jsp页面:src是一个方法地址
然后在Controller如下:写一个生成方法,用流进行读写
生成方法,(关键):
注意:这种方法可行,但是需要计算文字的位置,感觉不太灵活,如果谁有更好的方法请分享一下。
Graphics2D 的使用
1、Graphics2D和Graphics的区别
此 Graphics2D 类扩展Graphics 类,以提供对几何形状、坐标转换、颜色管理和文本布局更为复杂的控制。它是用于在Java(tm) 平台上呈现二维形状、文本和图像的基础类。
tips:总而言之Graphics2D是Graphics的加强版,增强了一些高级操作。
2、setRenderingHint的具体用处
为呈现算法设置单个首选项的值。提示类别包括对呈现过程中的呈现质量和总时间/质量折衷的控制。
tips:对呈现图像效果处理方式进行设置,例如抗锯齿、颜色、差值等各种效果的处理算法。(我现在主要觉得抗锯齿有用,以后会有不同的感受吧。)下面是两个对比图。
未开启抗锯齿
开启抗锯齿
下面是代码实现:
BufferedImage image = new BufferedImage(260, 80, BufferedImage.TYPE_INT_BGR);
//获取Graphics2D对象
Graphics2D graphics = image.createGraphics();
//开启文字抗锯齿
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
//设置字体
Font font = new Font("Algerian", Font.ITALIC, 40);
graphics.setFont(font);
//向画板上写字
graphics.drawString("This is test!", 10, 60);
graphics.dispose();
3、Stroke的使用方法
描绘一个 Shape 如同使用一支具有适当大小和形状的画笔描绘其轮廓。
tips:相当于画笔头,用来定义画出来的线条的特征;通过设置不同的参数来表现出各种不同的线条类型。更多详细介绍可以观看BasicStroke的用法这篇文章,里面有详细叙述。
下面是我自己写的一个小例子(指定背景图,并画一个树):
package com.msw.test;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
public class MyTest {
public static void main(String[] args) throws IOException {
BufferedImage image = new BufferedImage(400, 500, BufferedImage.TYPE_INT_BGR);
BufferedImage image2 = ImageIO.read(new FileInputStream(new File("F:\\2.jpg")));
// 获取Graphics2D对象
Graphics2D graphics = image.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION,RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
//把image2设置为背景图片
graphics.drawImage(image2, 0, 0, 400, 500,null);
// 设置画笔
Stroke stroke = new BasicStroke(5f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
graphics.setStroke(stroke);
// 设置颜色--绿色
graphics.setColor(Color.GREEN);
//画树
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Polygon polygon = new Polygon();
polygon.addPoint(200, 100);
polygon.addPoint(180, 150);
polygon.addPoint(220, 150);
graphics.draw(polygon);
polygon.reset();
polygon.addPoint(200, 150);
polygon.addPoint(160, 200);
polygon.addPoint(240, 200);
graphics.draw(polygon);
polygon.reset();
polygon.addPoint(200, 200);
polygon.addPoint(140, 250);
polygon.addPoint(260, 250);
graphics.draw(polygon);
polygon.reset();
polygon.addPoint(180, 250);
polygon.addPoint(180, 300);
polygon.addPoint(220, 300);
polygon.addPoint(220, 250);
graphics.draw(polygon);
graphics.dispose();
File file = new File("F:\\1.jpg");
file.createNewFile();
FileOutputStream fos = new FileOutputStream(file);
ImageIO.write(image, "jpg", fos);
fos.close();
}
}
使用Graphics2D图片上写字,计算宽和高 以及字体的位置
如上图,这个是一个有中文与英文的字符串。 中文与英文字符的宽高是不一样的,如果想要生成一张宽高刚的图片,这样我就需要计算每一个字符的宽度,及合适的高;
java.awt.FontMetrics 这个类对文字的宽高位置有详细的介绍;
计算使用字体的一段字符串的宽
public static int getWordWidth(Font font, String content) {
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int width = 0;
for (int i = 0; i < content.length(); i++) {
width += metrics.charWidth(content.charAt(i));
}
return width;
}
计算使用字体的最大的高度
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int height = metrics.getHeight();
在图片是写文字时最合适的位置
Ascent是从基线到顶部最大的高,也可以当做一个种字体画图时最有可以点用的高度
graphics.drawString(content, 0, metrics.getAscent());
测试代码
import sun.font.FontDesignMetrics;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.LineMetrics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
public class ImageTest {
public static void main(String[] args) throws IOException {
Font font = new Font("微软雅黑", Font.BOLD, 32);
String content = "你好Java!";
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int width = getWordWidth(font, content);//计算图片的宽
int height = metrics.getHeight();//计算高
BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = bufferedImage.createGraphics();
graphics.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
//设置背影为白色
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
graphics.setFont(font);
graphics.setColor(Color.BLACK);
graphics.drawString(content, 0, metrics.getAscent());//图片上写文字
graphics.dispose();
write(bufferedImage, "/data/test.png");
}
public static int getWordWidth(Font font, String content) {
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);
int width = 0;
for (int i = 0; i < content.length(); i++) {
width += metrics.charWidth(content.charAt(i));
}
return width;
}
public static void write(BufferedImage bufferedImage, String target) throws IOException {
File file = new File(target);
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
try (OutputStream os = new FileOutputStream(target)) {
ImageIO.write(bufferedImage, "PNG", os);
}
}
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。