Java 从HTML页面生成图片的几种方法

这篇博客介绍了三种将HTML转换为图片的JavaScript库:html2canvas、XHTMLRenderer和CSSBox。html2canvas是一个直接在浏览器中使用的JS插件,XHTMLRenderer需要HTML严格符合XML规范,而CSSBox则因其良好的兼容性受到推荐。文章提供了详细的使用示例和代码片段,包括如何处理图片和自定义元素工厂。
摘要由CSDN通过智能技术生成

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();
        }

    }

  • 0
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值