1. html2canvas
html2canvas是一款js插件,需要在浏览器中打开html页面,调用js函数生成图片。
1.1 使用示例
https://codeload.github.com/usecodelee/JavaScript-screenshot/zip/refs/heads/master
2.xhtmlrenderer
这款插件挺难用的,需要将html转成xhtml,必须严格符合xml的规范才可以,页面中的js css都不好解析。
2.1 maven添加引用
<!--html页面转图片的插件-->
<dependency>
<groupId>org.xhtmlrenderer</groupId>
<artifactId>core-renderer</artifactId>
<version>R8</version>
</dependency>
2.2 生成图片
package com.ailab.cdm.util;
import lombok.SneakyThrows;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xhtmlrenderer.extend.ReplacedElement;
import org.xhtmlrenderer.extend.ReplacedElementFactory;
import org.xhtmlrenderer.extend.UserAgentCallback;
import org.xhtmlrenderer.layout.LayoutContext;
import org.xhtmlrenderer.render.BlockBox;
import org.xhtmlrenderer.simple.extend.FormSubmissionListener;
import org.xhtmlrenderer.swing.ImageReplacedElement;
import org.xhtmlrenderer.swing.Java2DRenderer;
import javax.imageio.ImageIO;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
public class XHtmlUtil {
public static String generateImg(String html, int width, int height) throws Exception {
// 看代码
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document document = builder.parse(new ByteArrayInputStream(html.getBytes()));
Java2DRenderer renderer = new Java2DRenderer(document, width, height);
// 重点在这里,自定义工厂 处理img标签
renderer.getSharedContext().setReplacedElementFactory(new Base64ImgReplacedElementFactory());
renderer.getSharedContext().getTextRenderer().setSmoothingThreshold(1);
BufferedImage image = renderer.getImage();
try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
// 可以输出到流
ImageIO.write(image, "png", outputStream);
// 也可以直接保存到文件
ImageIO.write(image, "png", new File("D://test.png"));
return Base64.getEncoder().encodeToString(outputStream.toByteArray());
} catch (Exception e) {
throw new Exception("桌牌图片转换失败");
}
}
// 自定义元素工厂的代码
public static class Base64ImgReplacedElementFactory implements ReplacedElementFactory {
@SneakyThrows
@Override
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox, UserAgentCallback userAgentCallback, int width, int height) {
Element e = blockBox.getElement();
if (e == null) {
return null;
}
String nodeName = e.getNodeName();
if ("img".equals(nodeName)) {
// 这里直接从标签获取base64图片的值,如果是地址的话需要通过地址去获取图片
String attribute = e.getAttribute("src");
// 这里的width和height就是标签的css属性
try {
return new ImageReplacedElement(buildImage(attribute, userAgentCallback), width, height);
} catch (IOException ex) {
ex.printStackTrace();
}
}
return null;
}
/**
* 将base64编码解码并生成图像
*
* @param srcAttr 属性
* @param uac 回调
* @return FSImage
* @throws IOException io异常
*/
protected java.awt.Image buildImage(String srcAttr, UserAgentCallback uac) throws IOException {
if (srcAttr.startsWith("data:image/")) {
String b64encoded = srcAttr.substring(srcAttr.indexOf("base64,") + "base64,".length()
);
// 解码
byte[] decodedBytes = Base64.getDecoder().decode(b64encoded);
ByteArrayInputStream bais = new ByteArrayInputStream(decodedBytes);
return ImageIO.read(bais);
}
return null;
}
@Override
public void reset() { }
@Override
public void remove(Element element) { }
@Override
public void setFormSubmissionListener(FormSubmissionListener formSubmissionListener) { }
}
}
3.cssbox
这款插件是我用了最方便的,兼容性好。
3.1 添加maven引用
<dependency>
<groupId>net.sf.cssbox</groupId>
<artifactId>cssbox</artifactId>
<version>4.12</version>
</dependency>
3.2 生成图片
@Test
public void cssboxTest() {
try {
ImageRenderer render = new ImageRenderer();
System.out.println("start");
String url = "https://developers.weixin.qq.com/miniprogram/dev/component/canvas.html";/*网络链接的html*/
FileOutputStream out = new FileOutputStream(new File("D:"+File.separator+"html.png"));/*生成文件的路径*/
render.renderURL(url, out, ImageRenderer.Type.PNG);/*将url网页写入生成文件中*/
System.out.println("OK");
} catch (Exception e) {
e.printStackTrace();
}
}