1. 安装phantomjs
- pip install snapshot-phantomjs
- 下载phantomjs安装包,参见:https://phantomjs.org/download.html,不同系统下载不同的包
- 将下载下来的包解压后的bin目录下的二进制文件放到你的
$PATH
中,查看$PATH
的方式:echo $PATH
,这里我是放到了/usr/local/bin下
cp phantomjs-2.1.1-linux-x86_64/bin/phantomjs /usr/local/bin/phantomjs && chmod +x /usr/local/bin/phantomjs
2. 官方使用方法:
下面是官方的例子,我进行了一些小小的修改,允许执行宽和高,背景颜色,以及js的路径
from pyecharts import options as opts
from pyecharts.charts import Bar
from pyecharts.render import make_snapshot
from snapshot_phantomjs import snapshot
def bar_chart() -> Bar:
c = (
Bar(init_opts=opts.InitOpts(width=width, height=height, bg_color="white", js_host=file_path))
.add_xaxis(["衬衫", "毛衣", "领带", "裤子", "风衣", "高跟鞋", "袜子"])
.add_yaxis("商家A", [114, 55, 27, 101, 125, 27, 105])
.add_yaxis("商家B", [57, 134, 137, 129, 145, 60, 49])
.reversal_axis()
.set_series_opts(label_opts=opts.LabelOpts(position="right"))
.set_global_opts(title_opts=opts.TitleOpts(title="Bar-测试渲染图片"))
)
return c
make_snapshot(snapshot, bar_chart().render(), "bar.png")
3. 如果只是自己测试到这就算完成了,下面为部署到生产环境时遇到的一些问题
1. 我需要将生成的图片发送到企业微信中,但是生成的文件过大,企业微信最大允许发送2M的图片
- 先安装图像处理库
pip3 install pillow
- 对图片进行压缩代码:
from PIL import Image
import os
def get_size(file):
# 获取文件大小:KB
size = os.path.getsize(file)
return size / 1024
def get_outfile(infile, outfile):
if outfile:
return outfile
dir, suffix = os.path.splitext(infile)
outfile = '{}-out{}'.format(dir, suffix)
return outfile
def compress_image(infile, outfile='', mb=150, step=10, quality=80):
"""不改变图片尺寸压缩到指定大小
:param infile: 压缩源文件
:param outfile: 压缩文件保存地址
:param mb: 压缩目标,KB
:param step: 每次调整的压缩比率
:param quality: 初始压缩比率
:return: 压缩文件地址,压缩文件大小
"""
o_size = get_size(infile)
if o_size <= mb:
return infile
while o_size > mb:
im = Image.open(infile)
im.save(outfile, quality=quality)
if quality - step < 0:
break
quality -= step
o_size = get_size(outfile)
return outfile, get_size(outfile)
2. 线上是在容器中部署的服务,当执行生成图片时报错:
Auto configuration failed
140149858578048:error:25066067:DSO support routines:DLFCN_LOAD:could not load the shared library:dso_dlfcn.c:185:filename(libssl_conf.so): libssl_conf.so: cannot open shared object file: No such file or directory
140149858578048:error:25070067:DSO support routines:DSO_load:could not load the shared library:dso_lib.c:244:
140149858578048:error:0E07506E:configuration file routines:MODULE_LOAD_DSO:error loading dso:conf_mod.c:285:module=ssl_conf, path=ssl_conf
140149858578048:error:0E076071:configuration file routines:MODULE_RUN:unknown module name:conf_mod.c:222:module=ssl_conf
- 解决方案:
- export OPENSSL_CONF=/dev/null
- 重新执行就可以生成图片了
3. 在本地发送图片没问题,到了容器中phantomjs将html转换成图片时乱码,缺少文字库
- 解决方案:
-
在centos中执行:
yum install -y bitmap-fonts bitmap-fonts-cjk
-
在ubuntu中执行:
sudo apt-get install -y xfonts-wqy
-
4. 过了个国庆节回来发现代码没有任何变动但是不能用了,生成的html可以打开,但是转换成图片就报错:“ReferenceError: Can’t find variable: echarts\n\n undefined:1\nnull\n”
- 排错:
- 搜索有人说是需要代码的执行路径中不能包含中文,但是我本身的执行路径是没有中文的,
- 打开html文件发现echarts的引用是通过src引用的远程地址,猜测是否是远端拉不下来,但是在本地和服务器都是可以打开的,这个也被否定了
- 一度陷入僵局,谷歌并没有什么有用的信息
- 突然想起以前翻源码的时候在opts.InitOpts里面可以填写js_host的地址,那么我把js下载下来是否可行呢,试了下还真可以,问题就解决了,但是为啥使用远程引用的不可以有点不太理解
- 解决方案:
- 1.先把远程引用的js下载到本地,和执行的文件放在同一目录下
wget https://assets.pyecharts.org/assets/echarts.min.js
- 2.修改配置信息生成js引用地址的时候使用本地的js
- 1.先把远程引用的js下载到本地,和执行的文件放在同一目录下
file_path = "{}/".format(os.path.dirname(os.path.abspath(__file__)))
Bar(init_opts=opts.InitOpts(width=width, height=height, bg_color="white", js_host=file_path)))
这里主要看你哪里用的init_opts这个参数,没有的话可以在实例化图像实例的时候加上这个参数
- 3.重新执行图片就生成出来了
5. 生成的图片的背景是一堆的灰色方格,想要修改图片的背景颜色怎么办呢?
- 在生成html的时候就要进行修改,指定背景颜色,同样是
Bar(init_opts=opts.InitOpts(width=width, height=height, bg_color="white", js_host=file_path)))
里面的bg_color就是背景颜色,我这里指定的是白色
至此问题全部解决,Bingo.