phantomjs截图文字不显示、phantmjs文字不显示、phantomJS学习了解

吐槽、建议、解惑入口网址

PhantomJS 基于 webkit 内核的无界面浏览器

webkit:
webkit tutorial : https://www.paulirish.com/2013/webkit-for-developers/
中文了解:
https://www.jianshu.com/p/a129b05e2216

学习缘由

运营活动需要将用户这一年的数据展示出来,用户是可以截图的。
当时方案好几个:

  1. 用户自己手动截图,但是一个用户截图效果有可能会不太好,也太麻烦,最无奈的方案。
  2. 通过前端来完成给用户截图的功能。(后续被前端废弃。)
  3. 服务端对网页进行截图,然后用户直接下载。(推荐使用PhantomJS)

    使用过程和了解

    phantomjs官网
    下载包分为源码代码包和二进制代码包。

    (因为之前不明白centos RPM 包含源码代码包和二进制代码包,碰到了一些麻烦。)

phantmjs分平台的软件是二进制包,下载就可以使用。
但是值得注意的是mac和linux的平台上,有个细节linux需要依赖fonts。
一开始我们没有注意这个问题,才有今天的文章。在mac上截图很正常,但是centos服务器截图就是没有文字。

分析:
当时出现在服务器没有显示文字,不明白。

  1. 开始怀疑是字体颜色的问题,修改后发现没有效果。
  2. 再次认为是JS的原因,通过对请求生成的html进行输出和截图,发现有可能不是html的问题。
  3. 最后查阅相关资料,浏览器查找结果有些展示说是字体的问题(因为与字体有关,操作麻烦,直接放弃。想找简单的方法处理),最后没有办法才尝试,字体相关操作。

phantomjs实现服务端屏幕截图
这篇博客对linux服务端phantomJS截图的做了很深刻的讲解。但是字体使用是微软雅黑。按照这篇博客讲解操作,我们服务器这边截图的字体样式有点难看,太纤细了。

因此将字体变得好看成为重中之重。

  1. 查询当前MAC浏览器的字体是什么类型?? (WhatFont)查询字体 结果:PingFang SC
  2. 前端指定字体样式:font-family {} 没有效果
  3. 前端@font-face 下载字体 考虑网速的问题,需要压缩字体。没有执行
  4. 服务端寻找字体,放到服务器使用。 {最终解决方案} 首选字体PingFang SC

phantomjs在linux下截图中文字体问题
给我们很好的思路,尝试拷贝字体。

  1. 直接mac 命令行拷贝 没有权限失败。
  2. 通过mac 命令行 (open /) 打开系统文件,进行/System/Library/Fonts的PingFang.ttc 拖拽拷贝成功。
  3. 将PingFang.ttc 放置到linux指定位置
    1
    2
    3
     mkdir /usr/share/fonts/custom
    cp *.ttf /usr/share/fonts/custom
    fc-cache -fv

经过后续实操经验证明,其实Linux是能够接受ttc格式字体,而且经过压缩后ttf格式字体,存在大量字体丢失情况。
需要将PingFang.ttc的格式转换为linux可用ttf格式。上面博客推荐的转换地址发现,超过了上传文件最大限度。
1. Convert Font Files 这个网址转换成功。

但是新的问题:浏览器上使用的是PingFang SC字体。linux服务器使用的PingFang字体,导致看到和截图字体样式不一致。

linux 建立字体索引 更新缓存

  • mkfontscale
  • mkfontdir
  • fc-cache

附赠代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
> renderImage.js phantomJS 的执行js代码

"use strict";
var page = require('webpage').create();
var system = require('system'), pageWidth, pageHeight, pageUrl, format, quality, imagePath;
if (system.args.length != 7) {
console.log('Usage: renderImage.js <pageWidth pageHeight pageUrl format quality imagePath>');
phantom.exit(1);
} else {
pageWidth = system.args[1]
pageHeight = system.args[2];
pageUrl = system.args[3];
format = system.args[4];
quality = system.args[5];
imagePath = system.args[6];
}
page.viewportSize = { width: pageWidth, height: pageHeight };
page.open(pageUrl, function start(status) {
page.render(imagePath, {format: format, quality: quality});
phantom.exit();
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
> java 执行phantomJS的代码
/**
* 将网页渲染成图片
* format 图片格式 quality 图片质量(0~100)
* pageWidth 网页宽度 pageHeight 网页高度
*/
public static void renderImage(String phantomJSPath, String renderImageJSPath, int pageWidth, int pageHeight, String renderUrl, String format, int quality, String outPutImagePath) {
// 执行命令参数
List<String> params = Arrays.asList(phantomJSPath, renderImageJSPath, pageWidth + "", pageHeight + "", renderUrl, format, quality + "", outPutImagePath);

ProcessBuilder processBuilder = new ProcessBuilder()
.command(params);
try {
processBuilder.redirectError();
Process process = processBuilder.start();
InputStream processIS = process.getInputStream();
String output = IOUtils.toString(processIS);
logger.info("渲染成图片: {} -> {}", processBuilder.command(), output);
IOUtils.closeQuietly(processIS);
int result = process.waitFor();
if (result != 0) {
logger.warn("执行失败: {} -> {}", processBuilder.command(), output);
}
} catch (InterruptedException | IOException e) {
logger.warn("执行失败: {} -> {}", processBuilder.command(), e);
}
}

参考资料:
phantomjs实现服务端屏幕截图
phantomjs在linux下截图中文字体问题
phantmjs下载地址
PingFang sc字体的使用
phantomJS API

不曾拥有,所以努力。(坚持原创技术分享,您的支持将鼓励我继续创作!)