├── Readme.md ├── convert.js ├── event.json ├── function.json ├── index.js └── phantomjs /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # capture 3 | 4 | Lambda function to convert a URL to PNG, JPEG, or GIF using PhantomJS. 5 | 6 | ## Installation 7 | 8 | Add capture to your Apex project: 9 | 10 | ``` 11 | $ git submodule add https://github.com/apex/capture.git functions/capture 12 | ``` 13 | 14 | Deploy it: 15 | 16 | ``` 17 | $ apex deploy capture 18 | ``` 19 | 20 | Try it: 21 | 22 | ``` 23 | $ apex invoke capture < functions/capture/event.json 24 | ``` 25 | 26 | ## API 27 | 28 | Input: 29 | 30 | - `url` (string) URL to render 31 | - `format` (string) output format, one of 'png', 'jpeg', or 'gif' (default: 'png') 32 | - `viewport` (object) viewport size with .width and .height (default: 1024x800) 33 | - `clip` (object) clip rect with .top, .left, .width, and .height (default: none) 34 | - `zoom` (number) zoom factor (default: 1) 35 | - `wait` (number) wait time in milliseconds (default: 250) 36 | - `backgroundColor` (string) body background color (default: none) 37 | 38 | Output: 39 | 40 | - `capture` (string) base64 output 41 | 42 | ## Badges 43 | 44 | ![](https://img.shields.io/badge/license-MIT-blue.svg) 45 | ![](https://img.shields.io/badge/status-stable-green.svg) 46 | [![](http://apex.sh/images/badge.svg)](https://apex.sh/ping/) 47 | 48 | --- 49 | 50 | > [tjholowaychuk.com](http://tjholowaychuk.com)  ·  51 | > GitHub [@tj](https://github.com/tj)  ·  52 | > Twitter [@tjholowaychuk](https://twitter.com/tjholowaychuk) 53 | -------------------------------------------------------------------------------- /convert.js: -------------------------------------------------------------------------------- 1 | 2 | // TODO: pdf 3 | // TODO: retina 4 | 5 | var page = require('webpage').create() 6 | var system = require('system') 7 | 8 | var event = JSON.parse(system.args[1]) 9 | 10 | // clipping rect 11 | page.clipRect = event.clip 12 | 13 | // zoom factor 14 | page.zoomFactor = event.zoom || 1 15 | 16 | // viewport size 17 | page.viewportSize = event.viewport || { 18 | width: 1024, 19 | height: 800 20 | } 21 | 22 | // render the page 23 | page.open(event.url, function(status) { 24 | if (status != 'success') { 25 | console.log('error loading page') 26 | phantom.exit(1) 27 | } 28 | 29 | page.evaluate(function(color) { 30 | if (color) document.body.bgColor = color 31 | }, event.backgroundColor) 32 | 33 | window.setTimeout(function() { 34 | var format = event.format || 'png' 35 | system.stdout.write(page.renderBase64(format.toUpperCase())) 36 | phantom.exit() 37 | }, event.wait || 250) 38 | }) 39 | -------------------------------------------------------------------------------- /event.json: -------------------------------------------------------------------------------- 1 | { 2 | "url": "https://segment.com", 3 | "backgroundColor": "white", 4 | "format": "jpeg" 5 | } 6 | -------------------------------------------------------------------------------- /function.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Capture URL screenshots as an image", 3 | "memory": 1024, 4 | "timeout": 30, 5 | "runtime": "nodejs4.3" 6 | } 7 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | const proc = require('child_process') 3 | 4 | /** 5 | * Perform a screen capture via PhantomJS. 6 | */ 7 | 8 | exports.handle = (event, ctx, cb) => { 9 | if (!event.url) return cb(new Error('.url required')) 10 | 11 | try { 12 | const args = ['convert.js', JSON.stringify(event)] 13 | const capture = proc.execFileSync('./phantomjs', args).toString() 14 | cb(null, { capture }) 15 | } catch(err) { 16 | cb(err) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /phantomjs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apex/capture/92ea9668410a406c2f8ae07903d3dd7b4e7565ba/phantomjs --------------------------------------------------------------------------------