且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

开源)Java生成二维码分享海报(3)

更新时间:2022-09-16 19:42:44

第四步,将自动换行后的文本在海报背景上打印。


这里需要用到 FontDesignMetrics 的 getHeight() 方法获取每行文本的高度。对照下面的示意图,理解 height 的具体高度。


开源)Java生成二维码分享海报(3)


// 自动换行后的文本
String zhWrap = FontUtil.makeLineFeed(graphics2dPoster.getZh(), metrics, graphics2dPoster.getSuitableWidth());
// 拆分行
String[] zhWraps = zhWrap.split("\n");
// 将每一行在海报背景上打印
for (int i = 0; i < zhWraps.length; i++) {
    graphics2dPoster.addCurrentY(metrics.getHeight());
    graphics2d.drawString(zhWraps[i], MARGIN, graphics2dPoster.getCurrentY());
}



此时的海报效果如下图所示。

开源)Java生成二维码分享海报(3)



可以看得出,文字带有很强的锯齿感,怎么消除呢?


graphics2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);


如果英语不好的话,看起来这段代码会很吃力。ANTIALIASING 单词的意思就是“消除混叠现象,消除走样,图形保真”。


07、利用 Graphics2D 在海报上打印英文


英文和中文最大的不同在于,换行的单位不再是单个字符,而是整个单词。


第一步,根据当前字体下每个英文单词的宽度,以及海报可容纳的最大文本宽度,对文本进行换行。


public static String makeEnLineFeed(String en, FontDesignMetrics metrics, int max_width) {
    // 每个单词后追加空格
    char space = ' ';
    int spaceWidth = metrics.charWidth(space);
    // 按照空格对英文文本进行拆分
    String[] words = en.split(String.valueOf(space));
    // 利用 StringBuilder 对字符串进行修改
    StringBuilder sb = new StringBuilder();
    // 每行文本的宽度
    int len = 0;
    for (int i = 0; i < words.length; i++) {
  String word = words[i];
  int wordWidth = metrics.stringWidth(word);
  // 叠加当前单词的宽度
  len += wordWidth;
  // 超出最大宽度,进行换行
  if (len > max_width) {
    sb.append("\n");
    sb.append(word);
    sb.append(space);
    // 下一行的起始宽度
    len = wordWidth + spaceWidth;
  } else {
    sb.append(word);
    sb.append(space);
    // 多了一个空格
    len += spaceWidth;
  }
    }
    return sb.toString();
}

假如文本是“Fear can hold you ***er. Hope can set you free. It takes a strong man to save himself, and a great man to save another.”我们来通过 makeEnLineFeed() 方法试验一下。


Font font = new Font("微软雅黑", Font.PLAIN, 28);

FontDesignMetrics metrics = FontDesignMetrics.getMetrics(font);


String en = "Fear can hold you ***er. Hope can set you free. It takes a strong man to save himself, and a great man to save another.";

String[] rows = makeEnLineFeed(en, metrics, 600).split("\n");

for (int i = 0; i < rows.length; i++) {

System.out.println(rows[i]);

}


其结果如下所示。


Fear can hold you ***er. Hope can set

you free. It takes a strong man to save

himself, and a great man to save another.

第三步,将自动换行后的文本在海报背景上打印。


// 设置封面图和下方中文之间的距离
graphics2dPoster.addCurrentY(20);
Graphics2D graphics2d = graphics2dPoster.getGraphics2d();
graphics2d.setColor(new Color(157, 157, 157));
FontDesignMetrics metrics = FontDesignMetrics.getMetrics(graphics2d.getFont());
String enWrap = FontUtil.makeEnLineFeed(graphics2dPoster.getEn(), metrics, graphics2dPoster.getSuitableWidth());
String[] enWraps = enWrap.split("\n");
for (int i = 0; i < enWraps.length; i++) {
    graphics2dPoster.addCurrentY(metrics.getHeight());
    graphics2d.drawString(enWraps[i], MARGIN, graphics2dPoster.getCurrentY());
}

此时的海报效果如下图所示。

开源)Java生成二维码分享海报(3)