前言
笔者在项目中需要用到 node 绘图并返回,查询了市面上的 node 的绘图库
绘图库 | 不想用的理由 | canvas | 这个库吧安装要求,太多了,Python 版本要求 2.7,还要安装 GTK,gyp 什么的,因为已经安装了 py3.0 了改来改去也太麻烦了~。 | gm | 因为没找到这个库的渐变怎么做的资料,其他看起来挺好用的 |
---|
找来找去我想到可以利用 puppeteer进行绘图
介绍
大白话就是一个跑在 node 内部的浏览器,可以在这个浏览器中进行一些 node 不能做的操作,比如:生成网页的 PDF, 网页性能测试,模拟表单提交,爬取网页数据等等, 当然还有这篇文章的主题用puppeteer在 node 中绘图
gogogo
npm i puppeteer
1.封装一下获取浏览器实例
const puppeteer = require('puppeteer')
const mainConfig = require('./mainConfig')
class BrowserManage {
browserDestructionTimeout //清理浏览器实例
browserInstance //浏览器实例
browserState = 'closed' //浏览器状态
/**
* 用于长时间未进行操作时关闭浏览器实例
*/
scheduleBrowserForDestruction() {
clearTimeout(this.browserDestructionTimeout)
this.browserDestructionTimeout = setTimeout(async () => {
if (this.browserInstance) {
this.browserState = 'closed'
await this.browserInstance.close() //关闭浏览器实例
}
}, 5000)
}
/**
* 用于长时间未进行操作时关闭浏览器实例
*/
async getBrowser() {
return new Promise(async (resolve, reject) => {
if (this.browserState === 'closed') {
this.browserInstance = await puppeteer.launch(mainConfig.config.puppeteer) //开启浏览器实例
this.browserState = 'open'
resolve(this.browserInstance)
}
if (this.browserState === 'open') {
if (this.browserInstance) {
resolve(this.browserInstance)
}
}
})
}
}
module.exports = new BrowserManage()
这里的 mainConfig.config.puppeteer
为
{
args: ['--no-sandbox', '--disable-setuid-sandbox']
}
因为只用绘制功能所以,不会进行网页的跳转所以这里没有配置沙箱,如果你涉及了页面的跳转强烈建议你配置沙箱
2.定义 绘图函数
这里以绘制文字为例
exports.toImgData = async (options) => {
let fontConfig = {
baseLine: 5
}
function getColorX(i, colors) {
if (colors instanceof Array) {
return (i / (colors.length - 1)).toFixed(2)
}
}
return new Promise((resolve, reject) => {
let canvas = document.createElement('canvas')
let ctx = canvas.getContext('2d'),
font = options.text || '阿巴阿巴',
fontSize = Number(options.fontSize || 32),
fontFamily = options.fontFamily,
lineHeight = fontSize + fontSize / fontConfig.baseLine
canvas.width = fontSize * font.length
canvas.height = lineHeight
gradient = ctx.createLinearGradient(0, 0, canvas.width, 0)
ctx.shadowColor = options.shadowColor || ''
ctx.shadowOffsetX = options.shadowOffsetX || 2
ctx.shadowOffsetY = options.shadowOffsetY || 2
if (options.colors instanceof Array) {
//实现渐变颜色
for (let i = 0; i < options.colors.length; i++) {
gradient.addColorStop(getColorX(i, options.colors), options.colors[i])
}
} else if (typeof options.colors == 'string') {
gradient.addColorStop(0, options.colors)
} else {
// 默认颜色
gradient.addColorStop(0, 'rgba(241,158,194,1)')
}
ctx.font = fontSize + 'px ' + fontFamily
if (!options.mode || options.mode == '1') {
//mode ==1为实线
ctx.fillStyle = gradient
ctx.fillText(font, 0, fontSize)
} else if (options.mode == '2') {
//mode ==2为字体镂空效果
ctx.strokeStyle = gradient
ctx.strokeText(font, 0, fontSize)
}
ctx.restore()
const dataURI = canvas.toDataURL('image/png')
const base64 = dataURI.substr(22) // 22 =`data:image/png;base64,`.length
resolve(base64)
})
}
3.获取并使用浏览器页面实例
const browser = await browserManage.getBrowser()
const page = (await browser.pages())[0]
await page.setOfflineMode(true) //因为我们不需要进行网络资源读取,这样可以节省我可怜服务器的带宽
page.on('console', (msg) => console.log(msg.type(), msg.text())) //监听页面console事件
const base64 = await page.evaluate(toImgData, passedOptions)
browserManage.scheduleBrowserForDestruction()
const buffer = Buffer.from(base64, 'base64')
return buffer //返回Base64 编码的图片
这里注意 page.evaluate
函数
所以toImgData
中的getColorX
写在了内部
当然也可以把getColorX
函数抽离然后这样调用
await page.evaluate(getColorX) //就相当于把getColorX声明并定义
const base64 = await page.evaluate(toImgData, passedOptions)
- 效果如下
总结
本文介绍了 node 使用 puppeteer 进行绘图。
要注意的地方是如果在 linux 中绘制中文会出现空白的情况 因为在 linux 中默认是没有安装中文字符的进行安装即可
并且在 linux 中直接 npm i puppeteer
是启动不了的
需要自己安装 chromium
或者
sudo apt-get install gconf-service libasound2 libatk1.0-0 libatk-bridge2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget
然后
const browser = await puppeteer.launch({
executablePath: "/usr/bin/chromium-browser", //通过executablePath配置Chromium 的路径
......
报错这个
(node:28469) UnhandledPromiseRejectionWarning: Error: Failed to launch chrome!
[1025/150325.817887:ERROR:zygote_host_impl_linux.cc(89)]
是因为没配置沙箱,这样以无沙箱模式启动
const browser = await puppeteer.launch({
args: ['--no-sandbox', '--disable-setuid-sandbox']}
......
建议配置沙箱
例子 git 地址 github.com/lgldlk/pupp…
欢迎加入前端学习讨论群 qq 群号: 530496237
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!