我在使用wkhtmltoimage工具时,发现使用同样的HTML生成的图片的渲染和浏览器上渲染出来的效果不一样
这是使用浏览器渲染出来的样子
这是使用wkhtmltoimage工具作成的图片
在我调查原因之后,发现HTML渲染出来的效果不一样是因为wkhtmltoimage工具和我使用的浏览器引擎是不一样的,wkhtmltoimage用来呈现Html内容的引擎是(WebKit),而我使用的浏览器用来呈现Html内容的引擎是(Blink),而尽管 WebKit 和 Blink 都有一些 Web 标准,但它们是两个不同的渲染引擎,可能在处理某些 HTML 和 CSS 特性上有一些不同。
所以在这里我使用的解决方法是放弃使用wkhtmltoimage来将Html转为图片,使用其他的工具,这里我换的工具是puppeteer,puppeteer工具使用的引擎是Blink引擎,这和我使用的浏览器用来呈现Html内容的引擎一致,所以我尝试更换工具来作成图片。
这是我更换工具后使用相同的HTML结构做出的图片
接下来我会整理出来如何安装puppeteer工具,并使用它
1.安装nodejs和npm
Puppeteer是一个 Node.js 库,因此Puppeteer需要依赖于nodejs
首先执行安装nodejs
apt-get install nodejs
安装npm
apt-get install npm
安装完成之后执行nodejs -v和npm -v,确认是否安装成功
使用npm安装Puppeteer工具
npm install puppeteer
安装wget,因为需要使用wget在系统内安装google浏览器,puppeteer 是一个基于 Chrome的工具,用于控制、操纵和测试浏览器。
apt-get install wget
安装gnupg,它是一个用于提供加密和签名的开源工具套件,当添加新的软件源时,系统通常要求通过签名来验证软件包的真实性,所以需要gnupg确保下载并安装的软件包是由正确的发布方签名的。
apt-get install gnupg
安装google套件
wget -q -O -https://dl-ssl.google.com/linux/linux_signing_key.pub| apt-key add - \
&& sh -c 'echo "deb [arch=amd64]http://dl.google.com/linux/chrome/deb/stable main" >> /etc/apt/sources.list.d/google.list' \
&& apt-get update && apt-get install -y google-chrome-stable
其中,https://dl-ssl.google.com/linux/linux_signing_key.pub是Google Chrome 的签名密钥文件,用于验证下载软件包的完整性和真实性。
http://dl.google.com/linux/chrome/deb/是Google Chrome 的 Debian 软件包的存储库地址,包含了 Google Chrome 的二进制软件包,软件包存储库地址则指定了软件包的位置。
当执行了以上命令,在执行apt-get install -y google-chrome-stable命令后就会从http://dl.google.com/linux/chrome/deb/下下载并安装google浏览器。
到这里配置方面的工作就完成了,接下来我来介绍如何使用这个工具
在这里我使用了browsershot库
https://github.com/spatie/browsershot
安装browsershot
composer require spatie/browsershot
在代码中引入
use Spatie\Browsershot\Browsershot;
使用Browsershot库将HTML转为图片
Browsershot::html($dom)->setOption('args', ['--disable-setuid-sandbox','--font-render-hinting=medium'])->setScreenshotType('jpeg')->setNodeBinary(env('NODE_PATH', '/usr/bin/node'))->setNpmBinary(env('NPM_PATH', '/usr/bin/npm'))->setChromePath(env('CHROME_PATH', '/usr/bin/google-chrome-stable'))->windowSize(2500, 843)->delay(2000)->quality(80)->save($path);
在这里我解释一下以上代码的作用
Browsershot::html($dom)表示使用HTML结构来生成图片,$dom为HTML变量
->setOption('args', ['--disable-setuid-sandbox','--font-render-hinting=medium']) 这其中‘--disable-setuid-sandbox’是为了禁用google浏览器的沙箱模式,Chrome 的沙箱是为了提高安全性而设计的,但在容器中运行时,可能会导致权限问题,所以我们可以通过禁用沙箱,可以绕过这些问题。‘--font-render-hinting=medium’为了设置字体呈现的提示级别为中等。这个参数用于控制字体的渲染方式。
->setScreenshotType('jpeg') 设置截图的类型为 JPEG 格式。
->setNodeBinary(env('NODE_PATH', '/usr/bin/node')) 设置Node.js路径
->setNpmBinary(env('NPM_PATH', '/usr/bin/npm')) 设置npm路径
->setChromePath(env('CHROME_PATH', '/usr/bin/google-chrome-stable')) 设置Chrome 浏览器的二进制文件路径。
->windowSize(2500, 843) 设置截图的像素宽高比例。
->delay(2000) 表示在生成图片时延迟两秒的时间,因为我在渲染HTML时使用了部分字体文件,这部分字体文件较大所以渲染慢,在这里我在生成截图时延迟两秒,避免在字体还未渲染完成就生成图片。
->quality(80) 设置JPEG 图片的质量。
->save($path) 将最终的截图保存到指定路径。