很久很久以前,就觉得微博的长图文实现得非常有意思,将排版直接以最终的图片输出,收藏查看分享都很方便,现在则自己动手实现一个简单版本的

目标

首先定义下我们预期达到的目标:根据文字 + 图片生成长图文

目标拆解

代码如下:

int realAddH = Math.max(bufferedImage.getHeight() + options.getBottomPadding() + options.getTopPadding(), BASE_ADD_H)

重新生成画布实现 com.hust.hui.quickmedia.common.util.GraphicUtil#createImg

public static BufferedImage createImg(int w, int h, BufferedImage img) {
  BufferedImage bf = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
  Graphics2D g2d = bf.createGraphics();

  if (img != null) {
    g2d.setComposite(AlphaComposite.Src);
    g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.drawImage(img, 0, 0, null);
  }
  g2d.dispose();
  return bf;
}

上面理解之后,绘制图片就比较简单了,基本上行没什么差别

public Builder drawImage(String img) {
  BufferedImage bfImg;
  try {
    bfImg = ImageUtil.getImageByPath(img);
  } catch (IOException e) {
    log.error("load draw img error! img: {}, e:{}", img, e);
    throw new IllegalStateException("load draw img error! img: " + img, e);
  }

  return drawImage(bfImg);
}


public Builder drawImage(BufferedImage bufferedImage) {

  if (result == null) {
    result = GraphicUtil.createImg(options.getImgW(),
        Math.max(bufferedImage.getHeight() + options.getBottomPadding() + options.getTopPadding(), BASE_ADD_H),
        null);
  } else if (result.getHeight() < contentH + bufferedImage.getHeight() + options.getBottomPadding()) {
    // 超过阀值
    result = GraphicUtil.createImg(options.getImgW(),
        result.getHeight() + Math.max(bufferedImage.getHeight() + options.getBottomPadding() + options.getTopPadding(), BASE_ADD_H),
        result);
  }

  // 更新实际高度
  int h = GraphicUtil.drawImage(result,
      bufferedImage,
      contentH,
      options);
  contentH += h + options.getLinePadding();
  return this;
}

5. http接口

上面实现的生成图片的公共方法,在 quick-media 工程中,利用spring-boot搭建了一个web服务,提供了一个http接口,用于生成长图文,最终的成果就是我们开头的那个gif图的效果,相关代码就没啥好说的,有兴趣的可以直接查看工程源码,链接看最后

测试验证

上面基本上完成了我们预期的目标,接下来则是进行验证,测试代码比较简单,先准备一段文本,这里拉了一首诗

招魂酹翁宾?D

郑起

君之在世帝敕下,君之谢世帝敕回。

魂之为变性原返,气之为物情本开。

於戏龙兮凤兮神气盛,噫嘻鬼兮归兮大块埃。

身可朽名不可朽,骨可灰神不可灰。

采石捉月李白非醉,耒阳避水子美非灾。

长孙王吉命不夭,玉川老子诗不徘。

新城罗隐在奇特,钱塘潘阆终崔嵬。

阴兮魄兮曷往,阳兮魄兮曷来。

君其归来,故交寥落更散漫。

君来归来,帝城绚烂可徘徊。

君其归来,东西南北不可去。

君其归来。

春秋霜露令人哀。

花之明吾无与笑,叶之陨吾实若摧。

晓猿啸吾闻泪堕,宵鹤立吾见心猜。

玉泉其清可鉴,西湖其甘可杯。

孤山暖梅香可嗅,花翁葬荐菊之隈。

君其归来,可伴逋仙之梅,去此又奚之哉。

测试代码

@Test
public void testGenImg() throws IOException {
  int w = 400;
  int leftPadding = 10;
  int topPadding = 40;
  int bottomPadding = 40;
  int linePadding = 10;
  Font font = new Font("宋体", Font.PLAIN, 18);

  ImgCreateWrapper.Builder build = ImgCreateWrapper.build()
      .setImgW(w)
      .setLeftPadding(leftPadding)
      .setTopPadding(topPadding)
      .setBottomPadding(bottomPadding)
      .setLinePadding(linePadding)
      .setFont(font)
      .setAlignStyle(ImgCreateOptions.AlignStyle.CENTER)
//        .setBgImg(ImageUtil.getImageByPath("qrbg.jpg"))
      .setBgColor(0xFFF7EED6)
      ;


  BufferedReader reader = FileReadUtil.createLineRead("text/poem.txt");
  String line;
  int index = 0;
  while ((line = reader.readLine()) != null) {
    build.drawContent(line);

    if (++index == 5) {
      build.drawImage(ImageUtil.getImageByPath("https://static.oschina.net/uploads/img/201708/12175633_sOfz.png"));
    }

    if (index == 7) {
      build.setFontSize(25);
    }

    if (index == 10) {
      build.setFontSize(20);
      build.setFontColor(Color.RED);
    }
  }

  BufferedImage img = build.asImage();
  String out = Base64Util.encode(img, "png");
  System.out.println("<img src=\"data:image/png;base64," + out + "\" />");
}

输出图片

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

02-05 20:45
查看更多