使用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();
    		}
    	}
    }
    
  2. 自己实现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"));
    	}
    
    }
    

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

6. 官方文档

有兴趣进一步了解cssbox的小伙伴,可以移步cssbox官方文档

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kuo-Teng

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值