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

Feature request: Create render API that returns byte array #11142

Closed
sbressler opened this issue Mar 15, 2013 · 10 comments
Closed

Feature request: Create render API that returns byte array #11142

sbressler opened this issue Mar 15, 2013 · 10 comments

Comments

@sbressler
Copy link

This change provides a render API to get a screenshot as a base64 string. Can we add an even simpler API to get a byte array of image data? Would be useful to stream a rendered page back as it's generated.

@markstos
Copy link

I'm also interested in support for returning the rendered data as a stream, particularly if I can I pipe to other node modules, such as streaming the result to S3 for storage. Not sure if that would work in the context of PhantomJS.

@koutsenko
Copy link

And I'm also... What if I want to optimize image using another tools like pngquant?
It would be great for build scripts without transient writes to disk.
All the solutions I seen creating a temporary file.

Any news about this feature?

@markstos
Copy link

@koutsenko Regarding writing to disk, you could always use an in-memory file system if you are concerned about the performance of disk access. Ubuntu Linux provides /dev/shm for this purpose: http://www.cyberciti.biz/tips/what-is-devshm-and-its-practical-usage.html

@ispringer
Copy link

+1.

I'm writing a web server endpoint that takes a POST request containing HTML and returns a PNG as the response body (Content-Type: image/png). Currently, I have to resort to this:

var imageFile = "/tmp/" + randomString(8) + ".png";
page.render(imageFile);
var imageBytes = fs.read(imageFile, { mode: "b" }); // binary mode
fs.remove(imageFile);

which is not ideal, since I want the service to be as fast as possible.

@markstos
Copy link

@ismasan several Linux distros provided /dev/shm as a RAM disk. If you replace /tmp in your code with /dev/shm, you can write to memory instead of disk. You can likely create your own ramdisk if your OS doesn't provide one.

@ispringer
Copy link

I'm developing on OS X. I could create a RAM disk for my system, but I'd rather not make that a requirement for everyone else on my team.

I did find a better way to do this that doesn't require a temp file:

var imageBytes = atob(page.renderBase64("png"));

It's still not ideal, because it encodes to base64 and then decodes back to bytes, but it's definitely better than using a temp file.

Any chance PhantomJS can add an API that looks something like this:

var imageBytes = page.renderBytes();

?

@markstos
Copy link

@ispringer the temp dir could be a configuration variable that is set to /tmp for local development, where it doesn't matter if it's a fraction of a second slower, and then then /dev/shm for production.

Having an option to get back just the bytes is nice, but something needs to control the upper-bound of the size, to prevent malicious requests that exhaust memory. Along with the feature to get back just the bytes, it would then also be helpful add some kind of "max bytes" configuration option to Phantom with sane default, to avoid trying to fit extra huge renders into memory.

@ispringer
Copy link

@markstos, that's a good idea. Thanks. I may go with that until renderBytes is added, since /dev/shm will likely be faster than the base64 roundtrip.

@markstos
Copy link

@ispringer I have used /dev/shm to solve the same kind of problem in production before. The only downside is if there's a "leak" in the cleanup process somehow, causing the tmp files to accumulate in memory. There's a slight race-condition of files getting stuck there if the server unexpectedly terminates while the file has been written there, but not yet deleted. In practice, it seems unlikely to be a problem, but worth mentioning.

@ghost ghost removed the old.Type-Enhancement label Jan 29, 2018
@ariya
Copy link
Owner

ariya commented Dec 25, 2019

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!

@ariya ariya closed this as completed Dec 25, 2019
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

5 participants