Skip to content

Commit

Permalink
add functions to export page or svg to pdf and png formats (zserge#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
zserge committed Dec 2, 2018
1 parent 531737e commit b4edb94
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 0 deletions.
55 changes: 55 additions & 0 deletions chrome.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,6 +438,61 @@ func (c *chrome) bounds() (Bounds, error) {
return bounds.Bounds, err
}

func (c *chrome) pdf(width, height int) ([]byte, error) {
result, err := c.send("Page.printToPDF", h{
"paperWidth": float32(width) / 96,
"paperHeight": float32(height) / 96,
})
if err != nil {
return nil, err
}
pdf := struct {
Data []byte `json:"data"`
}{}
err = json.Unmarshal(result, &pdf)
return pdf.Data, err
}

func (c *chrome) png(x, y, width, height int, bg uint32, scale float32) ([]byte, error) {
if x == 0 && y == 0 && width == 0 && height == 0 {
// By default either use SVG size if it's an SVG, or use A4 page size
bounds, err := c.eval(`document.rootElement ? [document.rootElement.x.baseVal.value, document.rootElement.y.baseVal.value, document.rootElement.width.baseVal.value, document.rootElement.height.baseVal.value] : [0,0,816,1056]`)
if err != nil {
return nil, err
}
rect := make([]int, 4)
if err := json.Unmarshal(bounds, &rect); err != nil {
return nil, err
}
x, y, width, height = rect[0], rect[1], rect[2], rect[3]
}

_, err := c.send("Emulation.setDefaultBackgroundColorOverride", h{
"color": h{
"r": (bg >> 16) & 0xff,
"g": (bg >> 8) & 0xff,
"b": bg & 0xff,
"a": (bg >> 24) & 0xff,
},
})
if err != nil {
return nil, err
}
result, err := c.send("Page.captureScreenshot", h{
"clip": h{
"x": x, "y": y, "width": width, "height": height, "scale": scale,
},
})
if err != nil {
return nil, err
}
pdf := struct {
Data []byte `json:"data"`
}{}
err = json.Unmarshal(result, &pdf)
return pdf.Data, err
}

func (c *chrome) kill() error {
if c.ws != nil {
if err := c.ws.Close(); err != nil {
Expand Down
56 changes: 56 additions & 0 deletions export.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package lorca

import (
"fmt"
"io/ioutil"
"os"
)

const (
// PageA4Width is a width of an A4 page in pixels at 96dpi
PageA4Width = 816
// PageA4Height is a height of an A4 page in pixels at 96dpi
PageA4Height = 1056
)

// PDF converts a given URL (may be a local file) to a PDF file. Script is
// evaluated before the page is printed to PDF, you may modify the contents of
// the page there of wait until the page is fully rendered. Width and height
// are page bounds in pixels. PDF by default uses 96dpi density. For A4 page
// you may use PageA4Width and PageA4Height constants.
func PDF(url, script string, width, height int) ([]byte, error) {
return doHeadless(url, func(c *chrome) ([]byte, error) {
c.eval(script)
return c.pdf(width, height)
})
}

// PNG converts a given URL (may be a local file) to a PNG image. Script is
// evaluated before the "screenshot" is taken, so you can modify the contents
// of a URL there. Image bounds are provides in pixels. Background is in ARGB
// format, the default value of zero keeps the background transparent. Scale
// allows zooming the page in and out.
//
// This function is most convenient to convert SVG to PNG of different sizes,
// for example when preparing Lorca app icons.
func PNG(url, script string, x, y, width, height int, bg uint32, scale float32) ([]byte, error) {
return doHeadless(url, func(c *chrome) ([]byte, error) {
c.eval(script)
return c.png(x, y, width, height, bg, scale)
})
}

func doHeadless(url string, f func(c *chrome) ([]byte, error)) ([]byte, error) {
dir, err := ioutil.TempDir("", "lorca")
if err != nil {
return nil, err
}
defer os.RemoveAll(dir)
args := append(defaultChromeArgs, fmt.Sprintf("--user-data-dir=%s", dir), "--remote-debugging-port=0", "--headless", url)
chrome, err := newChromeWithArgs(ChromeExecutable(), args...)
if err != nil {
return nil, err
}
defer chrome.kill()
return f(chrome)
}

0 comments on commit b4edb94

Please sign in to comment.