Reputation: 562
I am taking a screenshot of a web page using the zoomFactor, and clipRect, I have it rendering at the correct size. I am stuck on how to put a local image on top of it so that it prints as a single image.
page.open(link, function(status) {
page.viewportSize = { width: 188, height: 195 };
var clipRect = page.evaluate(function() {
return document.querySelector("body").getBoundingClientRect();
});
page.clipRect = {
top: 0,
left: clipRect.left,
width: 188,
height: 195
};
page.zoomFactor = 0.20;
page.render(sku + '_Thumb.jpg', { format: 'jpg', quality: '100' });
console.log("Thumb Complete");
});
I tried injecting the local image into the DOM but had no luck, I thought I could maybe use ImageMagick CLI, but could not get it to run.
Upvotes: 4
Views: 411
Reputation: 16836
I tried injecting the local image into the DOM but had no luck
Imagine you could edit remote site html content - how could you possibly link an image to a file that's on another server and is not served? Of course that won't work because if you inject an image into a remote page's DOM, the image has to be accessible via http.
So let's try that first.
page.viewportSize = { width: 188, height: 195 };
page.open(link, function(status) {
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
// Inject remote image
page.evaluate(function(){
$("body").append("<div style='position: absolute; top:0; left: 0;z-index:9999'><img src='https://images.unsplash.com/photo-1461409971633-aa0e46732112?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&w=640&fit=max&s=bb401d13a08d6459b80bc63a0905a091'></div>");
});
});
// Let's make sure the remote image has time to load
setTimeout(function(){
var clipRect = page.evaluate(function() {
return document.querySelector("body").getBoundingClientRect();
});
page.clipRect = {
top: 0,
left: clipRect.left,
width: 188,
height: 195
};
page.zoomFactor = 0.20;
page.render('thumb.jpg', { format: 'jpg', quality: '100' });
console.log("Thumb Complete");
phantom.exit();
}, 3000);
});
The original thumb produced by your script looks this (I operated on cnn.com):
A thumb with injected remote image from Unsplash looks like this:
But having to make a local image available externally is not too convenient - what if you don't have an http server on the working machine or what if you work on a local computer behind a NAT?
Luckily there's a simple solution in the form a PhantomJS built-in server:
var server = require('webserver').create();
var fs = require("fs");
var image = fs.open("img.jpg", "rb");
var data = image.read();
var listening = server.listen(3000, function (request, response) {
console.log("GOT HTTP REQUEST");
response.statusCode = 200;
response.headers = {"Cache": "no-cache", "Content-Type": "image/jpeg"};
response.setEncoding("binary");
response.write(data);
response.close();
});
if (!listening) {
console.log("could not create web server listening on port " + port);
phantom.exit();
}
Hats off to this answer for tip on setting the correct binary encoding.
With this code in the script we're starting a local server on port 3000 just to serve a given image (for watermarking purposes or some such, I suppose). After that we just have to inject an image from the local address:
page.includeJs('http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js', function() {
page.evaluate(function(){
$("body").append("<div style='position: absolute; top:0; left: 0;z-index:9999'><img src='http://127.0.0.1:3000/'></div>");
});
});
Now that is a local image succesfully embedded in a thumbnail of a remote web page:
Upvotes: 2