Phantomjs: Rasterize.js renders black below a specific height when screen capture a long web page.

Created on 28 Jan 2014  路  15Comments  路  Source: ariya/phantomjs

Friends.

I am new to phantomjs, I am using it to create screenshots of web pages with user created content. It works fine with most of the pages, but I just found it doesn't work well with a quite long web page. The lower part of the image created by phantomjs is totally black.

I changed several parameters like page.viewPort.height / page.clipRect.height, but every time the black part starts at the same place, so I am curious why phantomjs can't render correctly below a certain height? Are there any parameters I need to tweak accordingly?

The problematic webpage is http://jianshu.io/notes/83391/snap_view and you could see an example of the output image here: http://prod-jianshu-cwb.b0.upaiyun.com/notes/images/83391/weibo/image_622f51e887bb.jpeg

I am using phantomjs 1.9.2, the way creating the image is phantomjs rasterize.js [webpage url] [destination file] and the rasterize.js I am using is here:

var page = require('webpage').create(),
    system = require('system'),
    address, output, size;

if (system.args.length < 3 || system.args.length > 5) {
  console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]');
  console.log('  paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"');
  phantom.exit(1);
} else {
  address = system.args[1];
  output = system.args[2];
  page.viewportSize = { width: 640, height: 600 };
  if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") {
    size = system.args[3].split('*');
    page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' }
    : { format: system.args[3], orientation: 'portrait', margin: '1cm' };
  }
  if (system.args.length > 4) {
    page.zoomFactor = system.args[4];
  }

  page.open(address, function (status) {
    if (status !== 'success') {
      console.log('Unable to load the address!');
      phantom.exit();
    } else {
      window.setTimeout(function () {
        page.render(output);
        phantom.exit();
      }, 1000);
    }
  });
}
stale

Most helpful comment

This just happened to me in version 2.1.1 in Ubuntu

All 15 comments

Hello!
I have exactly the same problem, and I'm using phantom 1.9.7 in OpenSUSE 11.4 32 bits. Same case, when I have a page that is too high, or in other words, have a lot of height, the same thing happens. And when It's not so large( in height) everything works fine!

And in my case I have a local html file, so I dont have network issues.

This is my js script executed directly in comand line:

var page = require("webpage").create();
page.open("/tmp/crop/phant2131519.html", function (status) {
console.log(status);
var height = page.evaluate(function() { return document.body.offsetHeight }),
width = page.evaluate(function() { return document.body.offsetWidth });
page.viewportSize = { height:height, width:width };
console.log('w: '+width+' h: '+height);
window.setTimeout(function() {
page.render("/tmp/crop/IMG600326.png");
phantom.exit();
},4500);
});

$ phantomjs js_script.js (that's the way to reproduce the error);

And the "/tmp/crop/phant2131519.html" file is a valid HTML file that opens correctly in browser. The point is It has 35100px height.

If It helps, I can upload the png and html file here.
Thanks.

I have exactly the same problem too

Which version of PhantomJS are you using? Tip: run 'phantomjs --version'.
1.9.7

What steps will reproduce the problem?

Load url which webpage is very lary(it's height over 30,000px) and run page.render()

What is the expected output? What do you see instead?

if document.body.scrollHeight over about 30,000 px (may be less or more),
when render the webpage ,the part of output image over 30,000px will black(if output image is jpg) or transparency(png);

Which operating system are you using?
win7

Did you use binary PhantomJS or did you compile it from source?
Binary

Please provide any additional information below.

js code

url = "http://locahost/a.php";
var page = new WebPage();
width = 1024;
height = 768;
output_file = "out.png"
page.viewportSize = { width: width, height: height };
page.onLoadFinished = function (status) {
    if (status !== 'success') {
        console.log("badness");
        phantom.exit(1);
    }
    console.log("Writing to " + output_file);
    page.render(output_file);
    phantom.exit();
}

page.open(url);

here is my a.php to build very height webpage

echo "<div style='width:500px;margin:0 auto;'>";
for($i=0;$i<50;$i++){
    echo "<h3>line $i </h3><br/>";
    echo '<img src="a7.jpg" alt=""/> <br/>';
    echo '<img src="a8.jpg" alt=""/> <br/>';

}
echo "</div>";

#document.body.scrollHeight

If the width or height of a page is larger than 32768, then the part wider or longer than 32768 x 32768 square will be black.
I'm not sure it's a problem of PhantomJS or the lib it use.

I think this problem is caused by this issue: https://github.com/ariya/phantomjs/issues/10054

matthewshoup had reported a related problem:
The canvas renders at higher than 32767px but the rendering engine still stops at 32767 pixels height so I see a partially filled canvas with most of the screen being a transparent background even with this fixed partitioned rendering approach.

This issue was closed, but it seems that the problem is still there.

Same issue here. This would be great to fix

This bug is still in 2.0.0.

I am having this issue as well. Any workarounds?

This just happened to me in version 2.1.1 in Ubuntu

I found a workaround. Take several screenshots with the right clipRect, then stitch them together with imagemagick. Of course, because we are talking about huge images, everything is difficult.

Assuming you have more disk than memory and CPU, convert to imagemagick's mpc format first, then manipulate. It reduces the risk of your process getting killed.

I'll clean up the code a bit and post it somewhere, but I'm afraid it's one of those things that are fiddly and you'll have to fiddle with it yourself until it works.

Well, I've gone and done it. https://www.npmjs.com/package/phantomjs-render-large-page let me know if it's useful, has any bugs, etc. All feedback is welcome.

I can confirm this is still an issue with version 2.1.1 (latest)

I've tried MrP's workaround and it doesn't work for me. Fails silently, no final PNG output, though I do see a temp file being created.

Hi, @sfrazer thanks for trying my workaround. What's your setup? How big is your page? I'll give it a try if you can point to a public URL.

It happened to me just now, also i can not calculate my page size by using getboundingclientrect() correctly, my phantomjs version is 2.1.1 and my pagesize is just 29141 px height

I'm having the same issue. Im using version 2.1.16

Due to our very limited maintenance capacity (see #14541 for more details), we need to prioritize our development focus on other tasks. Therefore, this issue will be automatically closed. In the future, if we see the need to attend to this issue again, then it will be reopened. Thank you for your contribution!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

mz3 picture mz3  路  5Comments

yisibl picture yisibl  路  5Comments

olee picture olee  路  4Comments

simplegroupware picture simplegroupware  路  5Comments

dhilipsiva picture dhilipsiva  路  4Comments