Skip to content
This repository has been archived by the owner on May 30, 2023. It is now read-only.

Add API to render a page to a string, encoded in base 64 #10547

Closed
detro opened this issue May 17, 2012 · 29 comments
Closed

Add API to render a page to a string, encoded in base 64 #10547

detro opened this issue May 17, 2012 · 29 comments
Milestone

Comments

@detro
Copy link
Collaborator

detro commented May 17, 2012

detroniz...@gmail.com commented:

A good start would be support for:

  • PNG
  • JPG
  • BMP

The API could be something like:

var p = require("webpage").create();

p.open("http://www.repubblica.it", function(status) {
if (status === "success") {
require("fs").write("img", "data:image/png;base64,"+p.renderBase64PNG(), "w");
}

});

This is important for the PhantomJS WebDriver: GhostDriver.

Disclaimer:
This issue was migrated on 2013-03-15 from the project's former issue tracker on Google Code, Issue #547.
🌟   10 people had starred this issue at the time of migration.

@detro
Copy link
Collaborator Author

detro commented May 17, 2012

@ariya
Copy link
Owner

ariya commented May 21, 2012

ariya.hi...@gmail.com commented:

Since this is very similar to issue 15, I suggest we merge them.

I think I like the idea of a function returning the rendering content (as image), as opposed to a special magic URL.

 
Metadata Updates

  • Label(s) removed:
    • Type-Defect
    • Priority-Low
  • Label(s) added:
    • Type-Enhancement
    • Priority-Medium
    • Component-Logic
    • Module-WebPage
  • Milestone updated: Release1.6 (was: ---)

@detro
Copy link
Collaborator Author

detro commented May 21, 2012

detroniz...@gmail.com commented:

I think this is a different approach to #15 though: but if We add an
api to read the image as raw bytes, and the ability to pass those raw
bytes to a webserver response object, than 15 can be fulfilled.

@ariya
Copy link
Owner

ariya commented May 21, 2012

ariya.hi...@gmail.com commented:

Raw data is possible as a further enhancement. As a start, I think base64 encoded image data should already work.

@trevordixon
Copy link

trevordi...@gmail.com commented:

I would prefer raw bytes. You could always btoa() it for base64.

@detro
Copy link
Collaborator Author

detro commented Jun 1, 2012

detroniz...@gmail.com commented:

@trevordixon: we don't have a bridge for ByteArrays yet in QtWebKit. When we do, raw bytes will be added.

@detro
Copy link
Collaborator Author

detro commented Jun 12, 2012

detroniz...@gmail.com commented:

 

 
Metadata Updates

  • Label(s) added:
    • webdriver

@ariya
Copy link
Owner

ariya commented Jun 15, 2012

ariya.hi...@gmail.com commented:

Landed in 51ab11c6d9.

@ariya
Copy link
Owner

ariya commented Jun 15, 2012

ariya.hi...@gmail.com commented:

Issue 15 has been merged into this issue.

@ariya
Copy link
Owner

ariya commented Jun 15, 2012

ariya.hi...@gmail.com commented:

Do we really need to render into JPG and BMP format at all?

@detro
Copy link
Collaborator Author

detro commented Jun 15, 2012

detroniz...@gmail.com commented:

I added it out of "completeness": it was few extra lines, and the code was all there.
You never know: some people even asked for unencoded bytes, remember? People have weird tastes :)

@ariya
Copy link
Owner

ariya commented Jun 15, 2012

ariya.hi...@gmail.com commented:

Regardless file format, I have possible suggestion for the API improvement. We can draw a similarity to 2-D Canvas, i.e. its getImageData function. Right now we still don't support binary data (and thus also no support for Canvas-compatible ImageData) but we need to keep that option open for the near future.

Making it similar to Canvas API, it could be as WebPage#getImageBase64. See also http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#pixel-manipulation.

Example:

var result = page.getImageBase64(0, 0, 600, 400);

We could make the arguments optional, e.g. getImageBase64() returns the entire rendered page.

Comments?

@detro
Copy link
Collaborator Author

detro commented Jun 15, 2012

detroniz...@gmail.com commented:

Wait, you are now talking about method signature (I don't have a preference - fine to use something else) and clipping (we could definitely add that as overloaded method).

The spirit of the getImageBase64 seems very tailored towards the Canvas manipulation though: a matrix of pixels to manipulate. But given the pixel-by-pixel nature, it's a BMP or something even more raw.

Or, I'm completely missing your point :)

@detro
Copy link
Collaborator Author

detro commented Jun 15, 2012

detroniz...@gmail.com commented:

In any case, those API are more "basic": get an image encoded in Base64, into a string. Nothing like canvas.

We could add those too, but I'd leave those "basic" API.

Also, those are needed to implement the WebDriver specs fully: once we have a more "canvassy" API, we could deprecate those and provide utility methods to achieve the same result, but passing through the canvassy stuff.

@ariya
Copy link
Owner

ariya commented Jun 17, 2012

ariya.hi...@gmail.com commented:

That's a good point, the canvas-like API makes more sense if the actual getImageData() exists (and thus the users can draw the analog). Otherwise, it's kinda confusing.

@ariya
Copy link
Owner

ariya commented Jun 17, 2012

ariya.hi...@gmail.com commented:

Also, after playing with it for a while, and assuming most people wants PNG (lossless and still good compression) so it can be the default, what about having only (already private) this function

renderBase64(format = 'PNG');

as opposed to 3 different ones. What do you think?

@detro
Copy link
Collaborator Author

detro commented Jun 17, 2012

detroniz...@gmail.com commented:

It was a dilemma for me: use 1 method and pass a parameter to choose the
format, or make the format part of the signature?

I ended up choosing the signature as it was just 1 parameter and JS doesn't
have enums (in the C++ way).

We can change it: my personal preference is with the way it is now, but we
could even add a 4th "renderBase64(format = "png")" as you suggest. But
this makes it 4 methods...

@ariya
Copy link
Owner

ariya commented Jun 17, 2012

ariya.hi...@gmail.com commented:

That was my line of thought as well. However, I make an assumption here that most people will want PNG 99% of the time, hence it'll be only 'renderBase64()' we are going to see in many places.

@detro
Copy link
Collaborator Author

detro commented Jun 18, 2012

@ariya
Copy link
Owner

ariya commented Jun 19, 2012

ariya.hi...@gmail.com commented:

 

 
Metadata Updates

  • Status updated: Fixed

@ariya ariya closed this as completed Jun 19, 2012
@ariya
Copy link
Owner

ariya commented Dec 1, 2012

ariya.hi...@gmail.com commented:

Issue 565 has been merged into this issue.

@ariya
Copy link
Owner

ariya commented Dec 19, 2012

ariya.hi...@gmail.com commented:

Issue 540 has been merged into this issue.

@toramanan
Copy link

Hi,
Does this method supports PDF formats as well? I tried with 1.9 and it does not render anything. Is there any other way to generate PDF as base64 and flush it. Thanks for your excellent work.

@ariya
Copy link
Owner

ariya commented Mar 31, 2013

@toramanan Please file a separate feature request on PDF base64 render.

@toramanan
Copy link

Its done. Thanks Ariya.

#11192

@julien-c
Copy link

julien-c commented Feb 6, 2015

Hi,
Is there any reason why renderBase64 should be significantly slower than render? In my experience (512x512 viewport) it is approx. 2x slower (30ms instead of 15ms).
Looks like this blogpost reports the same: http://kfalck.net/2014/08/18/phantomjs-render-performance

Is this simply the hit of encoding to base64?

Let me know if I should open another issue.

Thanks!

@wonderdogone
Copy link

might render have an "end" event?
such to listen for the end of this
page.render('./files, {format: 'jpeg', quality: '80'});

@katrotz
Copy link

katrotz commented Dec 17, 2015

@wonderdogone Good point, I also found that the method is not fully synchronous, so I have to use setTimeout to start reading the generated file

@wonderdogone
Copy link

Yep. Knowing it's not only me I will look at the source and see if we can help this. It' been an issue for me a few times unless I am missing something obvious.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants