This repository has been archived by the owner on Aug 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 43
/
url-to-image.js
124 lines (104 loc) · 3.34 KB
/
url-to-image.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
'use strict';
// PhantomJS script
// Takes screeshot of a given page. This correctly handles pages which
// dynamically load content making AJAX requests.
// Instead of waiting fixed amount of time before rendering, we give a short
// time for the page to make additional requests.
// Phantom internals
const system = require('system');
const webPage = require('webpage');
function main() {
// I tried to use yargs as a nicer commandline option parser but
// it doesn't run in phantomjs environment
const args = system.args;
const opts = {
url: args[1],
filePath: args[2],
width: args[3],
height: args[4],
requestTimeout: args[5],
maxTimeout: args[6],
verbose: args[7] === 'true',
fileType: args[8],
fileQuality: args[9] ? args[9] : 100,
cropWidth: args[10],
cropHeight: args[11],
cropOffsetLeft: args[12] ? args[12] : 0,
cropOffsetTop: args[13] ? args[13] : 0
};
renderPage(opts);
}
function renderPage(opts) {
let requestCount = 0;
let forceRenderTimeout;
let dynamicRenderTimeout;
const page = webPage.create();
page.viewportSize = {
width: opts.width,
height: opts.height
};
// Silence confirmation messages and errors
page.onConfirm = page.onPrompt = function noOp() {};
page.onError = function(err) {
log('Page error:', err);
};
page.onResourceRequested = function(request) {
log('->', request.method, request.url);
requestCount += 1;
clearTimeout(dynamicRenderTimeout);
};
page.onResourceReceived = function(response) {
if (!response.stage || response.stage === 'end') {
log('<-', response.status, response.url);
requestCount -= 1;
if (requestCount === 0) {
dynamicRenderTimeout = setTimeout(renderAndExit, opts.requestTimeout);
}
}
};
page.open(opts.url, function(status) {
if (status !== 'success') {
log('Unable to load url:', opts.url);
phantom.exit(10);
} else {
forceRenderTimeout = setTimeout(renderAndExit, opts.maxTimeout);
}
});
function log() {
// PhantomJS doesn't stringify objects very well, doing that manually
if (opts.verbose) {
let args = Array.prototype.slice.call(arguments);
let str = '';
args.forEach(function(arg) {
if (isString) {
str += arg;
} else {
str += JSON.stringify(arg, null, 2);
}
str += ' '
});
console.log(str);
}
}
function renderAndExit() {
log('Render screenshot..');
if(opts.cropWidth && opts.cropHeight) {
log("Cropping...");
page.clipRect = {top: opts.cropOffsetTop, left: opts.cropOffsetLeft, width: opts.cropWidth, height: opts.cropHeight};
}
let renderOpts = {
fileQuality: opts.fileQuality
};
if(opts.fileType) {
log("Adjusting File Type...");
renderOpts.fileType = opts.fileType;
}
page.render(opts.filePath, renderOpts);
log('Done.');
phantom.exit();
}
}
function isString(value) {
return typeof value === 'string'
}
main();