使用5.0.0版本的cssbox将html文件转为图片文件,并解决字体显示问题

简介: 使用5.0.0版本的cssbox将html文件转为图片文件,并解决字体显示问题


在我的另一篇博客 使用cssbox将html文件转为图片文件中,大家可能对于cssbox渲染出来的图片的效果并不是特别满意,那么如何提升渲染效果呢?使用5.0.0版本的cssbox试试吧!

1. 引入依赖

<dependency>
    <groupId>net.sf.cssbox</groupId>
    <artifactId>cssbox</artifactId>
    <version>5.0.0</version>
</dependency>


2. 编写Util类

public class Html2ImageUtil {
  public static void transferHtml2Image(String htmlFilePath, String imageFilePath, Integer width, Integer height) {
    ImageRenderer render = new ImageRenderer();
    render.setWindowSize(new Dimension(width, height), false);
    String url = new File(htmlFilePath).toURI().toString();
    try {
      FileOutputStream out = new FileOutputStream(imageFilePath);
      render.renderURL(url, out, ImageRenderer.Type.PNG);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}


3. 调用Util

Html2ImageUtil.transferHtml2Image("result.html", "result.png", WIDTH_IMAGE, HEIGHT_IMAGE);


然后就可在项目根目录下找到生成的名为"result.png"的图片文件啦。

4. 存在的问题

通过这种方式渲染出来的图片可能存在字体的问题,比如无法正常展示汉字,或展示为异形字,如何解决这一问题呢?请往下面看~

5. 解决字体不兼容问题

在目前的操作中,我们直接使用了封装好的ImageRenderer类,该类有一些属性没有对外提供接口,因此我们需要自己实现这个类,并改变一些属性;

  1. Html2ImageUtil类的代码改为:
public class Html2ImageUtil {
  public static void transferHtml2Image(String htmlFilePath, String imageFilePath, Integer width, Integer height) {
    ImageRendererUtil render = new ImageRendererUtil();
    render.setWindowSize(new Dimension(width, height), false);
    String url = new File(htmlFilePath).toURI().toString();
    try {
      FileOutputStream out = new FileOutputStream(imageFilePath);
      render.renderURL(url, out);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
}


自己实现ImageRendererUtil这个类,直接将封装好的ImageRenderer类代码复制过来即可;然后添加contentCanvas.setUseKerning(false);这句代码即可;

public class ImageRendererUtil {
  private String mediaType = "screen";
  private Dimension windowSize;
  private boolean cropWindow;
  private boolean loadImages = true;
  private boolean loadBackgroundImages = true;
  private static final Integer DEFAULT_WIDTH = 1200;
  private static final Integer DEFAULT_HEIGHT = 600;
  private static final String FTP = "ftp:";
  private static final String HTTP = "http:";
  private static final String HTTPS = "https:";
  public ImageRendererUtil() {
    windowSize = new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);
  }
  public void setMediaType(String media) {
    mediaType = new String(media);
  }
  public void setWindowSize(Dimension size, boolean crop) {
    windowSize = new Dimension(size);
    cropWindow = crop;
  }
  public void setLoadImages(boolean content, boolean background) {
    loadImages = content;
    loadBackgroundImages = background;
  }
  /**
   * Renders the URL and prints the result to the specified output stream in the specified
   * format.
   * @param urlstring the source URL
   * @param out output stream
   * @return true in case of success, false otherwise
   * @throws SAXException
   */
  public boolean renderURL(String urlstring, OutputStream out) throws IOException, SAXException {
    if (!urlstring.startsWith(HTTP) && !urlstring.startsWith(HTTPS) && !urlstring.startsWith(FTP)
      && !urlstring.startsWith("file:")) {
      urlstring = "http://" + urlstring;
    }
    //Open the network connection
    DocumentSource docSource = new DefaultDocumentSource(urlstring);
    //Parse the input document
    DOMSource parser = new DefaultDOMSource(docSource);
    Document doc = parser.parse();
    //create the media specification
    MediaSpec media = new MediaSpec(mediaType);
    media.setDimensions(windowSize.width, windowSize.height);
    media.setDeviceDimensions(windowSize.width, windowSize.height);
    //Create the CSS analyzer
    DOMAnalyzer da = new DOMAnalyzer(doc, docSource.getURL());
    da.setMediaSpec(media);
    da.attributesToStyles();
    da.addStyleSheet(null, CSSNorm.stdStyleSheet(), DOMAnalyzer.Origin.AGENT);
    da.addStyleSheet(null, CSSNorm.userStyleSheet(), DOMAnalyzer.Origin.AGENT);
    da.addStyleSheet(null, CSSNorm.formsStyleSheet(), DOMAnalyzer.Origin.AGENT);
    da.getStyleSheets();
    GraphicsEngine contentCanvas = new GraphicsEngine(da.getRoot(), da, docSource.getURL());
    contentCanvas.setAutoMediaUpdate(false);
    contentCanvas.getConfig().setClipViewport(cropWindow);
    contentCanvas.getConfig().setLoadImages(loadImages);
    contentCanvas.getConfig().setLoadBackgroundImages(loadBackgroundImages);
    contentCanvas.setUseKerning(false);
    contentCanvas.createLayout(windowSize);
    ImageIO.write(contentCanvas.getImage(), "png", out);
    docSource.close();
    return true;
  }
  /**
   * Sets some common fonts as the defaults for generic font families.
   */
  protected void defineLogicalFonts(BrowserConfig config) {
    config.setLogicalFont(BrowserConfig.SERIF, Arrays.asList("Times", "Times New Roman"));
    config.setLogicalFont(BrowserConfig.SANS_SERIF, Arrays.asList("Arial", "Helvetica"));
    config.setLogicalFont(BrowserConfig.MONOSPACE, Arrays.asList("Courier New", "Courier"));
  }
}


这时,字体就恢复正常啦!

目录
相关文章
|
2月前
|
Java
有关Java发送邮件信息(支持附件、html文件模板发送)
有关Java发送邮件信息(支持附件、html文件模板发送)
35 1
|
2月前
如何在HTML文件中添加超链接
如何在HTML文件中添加超链接
24 0
|
2月前
|
Python
DTL与普通的HTML文件的区别
DTL与普通的HTML文件的区别。
67 5
N..
|
2月前
|
移动开发 前端开发 JavaScript
HTML文件
HTML文件
N..
13 1
|
29天前
|
移动开发
uni-app使用v-html输出富文本图片溢出解决
uni-app使用v-html输出富文本图片溢出解决
40 1
|
5天前
|
JSON JavaScript 数据格式
python遍历目录文件_结合vue获取所有的html文件并且展示
python遍历目录文件_结合vue获取所有的html文件并且展示
4 0
|
5天前
在线拼接图片工具HTML源码
在线将多张图片拼接成一张图片,多图合一并导出下载。 无需本地安装软件。 下载时,使用日期时间作为文件名, 规避图片文件名相同造成的覆盖问题;也能省去一部覆盖确认操作 多语言支持
8 0
在线拼接图片工具HTML源码
|
7天前
【代码片段】【HTML】弹出对话框点选加载文件
【代码片段】【HTML】弹出对话框点选加载文件
13 1
|
8天前
|
Python
python html(文件/url/html字符串)转pdf
python html(文件/url/html字符串)转pdf
9 0
|
14天前
|
XML 移动开发 前端开发
HTML版本
【4月更文挑战第16天】HTML版本
17 4