【问题标题】:How to improve PDF rasterization quality in PhantomJS?如何提高 PhantomJS 中的 PDF 光栅化质量?
【发布时间】:2018-03-27 19:01:03
【问题描述】:

我正在使用PhantomJS 打印一个网页,其中包括文本和图表等多个元素(在 ChartJS 中)。文本看起来不错,但图表和图像看起来嘈杂且像素化。见:

注意图表边框是如何像素化的。这一定是 PhantomJS 光栅化问题,但没有找到任何设置来提高生成的 PDF 或光栅化过程的质量。

我试过了:

  • 使用page.dpi = 200; 增加 DPI。好像没什么效果。
  • 使用page.property('dpi', 200); 增加 DPI。一样,没有效果。
  • 像这样增加视口大小page.property('viewportSize', { width: 1920, height: 1080 });。增加屏幕尺寸,但质量保持不变。

这是我当前的脚本:

const phantom = require('phantom');
let url = "http://localhost:3000/";

phantom.create().then(function(ph) {
    ph.createPage().then(function(page) {
        page.property('viewportSize', { width: 1920, height: 1080 });
        page.property('dpi', 200); //No effect?
        page.dpi = 200; //No effect?
        page.property('paperSize', { format: 'Letter', orientation: 'portrait' });
        //page.property('zoomFactor', 3.5); //Works erratically

        page.open(url).then(function(status) {
            setTimeout(function () {
              page.render("output-" + Date.now() + ".pdf", { format: "pdf" }).then(function() {
                console.log('Page Rendered');
                ph.exit();
              });
            }, 3000); //Change timeout as required to allow sufficient time
        });
    });
});

如何提高 PDF 光栅化/DPI 质量?

【问题讨论】:

    标签: charts printing phantomjs chart.js dpi


    【解决方案1】:

    我不熟悉 PhantomJS。

    我遇到了类似的问题,通过设置包含图表的容器的宽度和高度来解决

    <div id="container" style="width: 1920px; height: 1080px;">
        <canvas id="canvas"></canvas>
    </div>
    

    我还添加了一个不可见的图像标签,没有来源

    <img src="" alt="Chart" id="chartImg" style="display: none;"/>
    

    并注册了一个插件

    Chart.plugins.register({
        id: 'charttoimg',
        beforeRender: function(chart, options) {
            document.getElementById('container').style.width='1920px';
            document.getElementById('container').style.height='1080px';
        },
        afterRender: function(chart, options) {
            document.getElementById('chartImg').src=chart.chart.canvas.toDataURL('image/png');
            document.getElementById('container').style.width='75%';
            document.getElementById('container').style.height='';
        }
    });
    

    通过以下方法,我捕获了打印事件以在打印前后切换图像和容器

    (function() {
        var beforePrint = function() {
            document.getElementById('container').style.display='none';
            document.getElementById('chartImg').style.display='inline';
        };
        var afterPrint = function() {
            document.getElementById('chartImg').style.display='none';
            document.getElementById('container').style.display='block';
        };
        if (window.matchMedia) {
            var mediaQueryList = window.matchMedia('print');
            mediaQueryList.addListener(function(mql) {
                if (mql.matches) {
                    beforePrint();
                } else {
                    afterPrint();
                }
            });
        }
        window.onbeforeprint = beforePrint;
        window.onafterprint = afterPrint;
    }());
    

    【讨论】:

      【解决方案2】:

      现在在 2021 年,Chart.js 具有参数“devicePixelRatio”来提高质量。 在我的例子中,我将值设置为 1.5 以获得高分辨率,也适合使用 PDF 打印。

      options:{
            devicePixelRatio: 1.5
      }
      

      文档:https://www.chartjs.org/docs/3.0.2/configuration/device-pixel-ratio.html

      【讨论】:

        猜你喜欢
        • 2014-02-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-30
        • 1970-01-01
        • 2020-01-30
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多