13

HTML から画像 (jpg または png) を生成しようとしていますが、すでに PhantomJS (php の jonnyw/php-phantomjs 経由) と wkhtmltoimage を試しましたが、画像を生成するときに両方とも同じ問題を抱えています。境界線の半径、画像、またはフォントはすべて、ギザギザのエッジが非常に悪く、まったく鮮明ではありません。

最初はフォントがロードされていないと思っていましたが、私のフォントアイコンは正常に動作しています。本当に品質が悪いだけです。私は 100 の品質セットを持っており、どの Web サイトでも Phantomjs または wkhtmltoimage を使用しても同じ結果が得られます。

ここに画像の説明を入力

誰がこれを引き起こしているのか知っていますか?

アップデート

ここに画像の説明を入力

更新 2

jonnyw/php-phantomjs から使用されるコードは次のとおりです。

        $client = Client::getInstance();
        $client->isLazy();
        $client->getEngine()->setPath('phantomjs');
        $client->getEngine()->debug(true);

        $width  = 560;
        $height = 670;
        $top    = 1;
        $left   = 1;

        $request = $client->getMessageFactory()->createCaptureRequest('https://myurltoscreengrab.com', 'GET');
        $request->setOutputFile('uploads/stats/test.png');
        $request->setFormat('png');

        $request->setViewportSize($width, $height);
        $request->setCaptureDimensions($width, $height, $top, $left);

        $response = $client->getMessageFactory()->createResponse();

        // Send the request
        $client->send($request, $response);

使用されているJS

/**
 * Set up page and script parameters
 */
var page       = require('webpage').create(),
    system     = require('system'),
    response   = {},
    debug      = [],
    logs       = [],
    procedure  = {},
    resources  = 0,
    timeout;

/**
 * Global variables
 */


/**
 * Define width & height of capture
 */


var rectTop    = 1,
    rectLeft   = 1,
    rectWidth  = 530,
    rectHeight = 670;

if(rectWidth && rectHeight) {

    debug.push(new Date().toISOString().slice(0, -5) + ' [INFO] PhantomJS - Set capture clipping size ~ top: ' + rectTop + ' left: ' + rectLeft + ' ' + rectWidth + 'x' + rectHeight);

    page.clipRect = {
        top: rectTop,
        left: rectLeft,
        width: rectWidth,
        height: rectHeight
    };
}


/**
 * Define paper size.
 */


/**
 * Define viewport size.
 */

var viewportWidth  = 530,
    viewportHeight = 670;

if(viewportWidth && viewportHeight) {

    debug.push(new Date().toISOString().slice(0, -5) + ' [INFO] PhantomJS - Set viewport size ~ width: ' + viewportWidth + ' height: ' + viewportHeight);

    page.viewportSize = {
        width: viewportWidth,
        height: viewportHeight
    };
}




/**
 * Define custom headers.
 */

page.customHeaders = {};



/**
 * Page settings
 */

page.settings.resourceTimeout = 5000;



/**
 * On resource timeout
 */
page.onResourceTimeout = function (error) {

response        = error;
response.status = error.errorCode;


};

/**
 * On resource requested
 */
page.onResourceRequested = function (req) {





    resources++;
    window.clearTimeout(timeout);
};

/**
 * On resource received
 */
page.onResourceReceived = function (res) {

    var resource = res; // To be removed in version 5.0


if(!response.status) {
    response = resource;
}



    if(!res.stage || res.stage === 'end') {

        resources--;

        if (resources === 0) {

            timeout = window.setTimeout(function() {
                procedure.execute('success');
            }, 300);
        }
    }
};

/**
 * Handle page errors
 */
page.onError = function (msg, trace) {

var error = {
    message: msg,
    trace: []
};

trace.forEach(function(t) {
    error.trace.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
});

logs.push(error);


};

/**
 * Handle global errors
 */
phantom.onError = function(msg, trace) {

var stack = [];

trace.forEach(function(t) {
    stack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function + ')' : ''));
});

response.status  = 500;
response.content = msg;
response.console = stack;

system.stdout.write(JSON.stringify(response, undefined, 4));
phantom.exit(1);


};

/**
 * Open page
 */
page.open ('https://boxstat.co/widgets/image/stats/2898784/18/500/FFFFFF-EEEEEE-fafafa-333333-85bd4d-ffffff-e4f8cf-71b42f-fddfc1-bd6610-fad3c9-c85639-fac9c9-c52e2e', 'GET', '', function (status) {


page.evaluate(function() {

    var styles = {};

    for(var property in styles) {
        document.body.style[property] = styles[property];
    }
});

    window.setTimeout(function () { 
        procedure.execute(status); 
    }, 4800);
});

/**
 * Execute procedure
 */
procedure.execute = function (status) {

if (status === 'success') {

    try {

        page.render('uploads/stats/test.png', {
            format: 'png',
            quality: 100,
        });

        response.content = page.evaluate(function () {
            return document.getElementsByTagName('html')[0].innerHTML
        });

    } catch(e) {

        response.status  = 500;
        response.content = e.message;
    }
}

response.console = logs;

system.stderr.write(debug.join('\\n') + '\\n');
system.stdout.write(JSON.stringify(response, undefined, 4));

phantom.exit();

};
4

1 に答える 1