Documentation
¶
Overview ¶
Package convert turns pictures into a PDF and a PDF back into pictures.
Everything either side of the PDF was already here: github.com/go-pdfkit/pdfkit writes one and can place an image on a page, and github.com/go-pdfkit/render draws a page into a raster. What was missing was the join — which is why this package is wiring and codecs rather than a new engine.
Formats ¶
Reading: PNG, JPEG and GIF from the standard library; BMP, TIFF and WebP from golang.org/x/image. Writing: PNG, JPEG, GIF, BMP and TIFF.
⛔ There is no WebP ENCODER in pure Go, so FromPDF refuses "webp" by name instead of quietly writing something else. A converter that answers a request it did not carry out is worse than one that says no.
What decides the page ¶
A picture has pixels and a DPI; a PDF page has points. ToPDF sizes each page to its picture at the DPI given, so a 300-dpi scan comes back the size of the paper it came off. Asking for a fixed page size instead fits the picture inside it, centred, never cropping and never stretching: see Options.Page.
Pure Go ¶
CGO-free, including GOOS=js. No C anywhere in the chain.
Index ¶
- Constants
- func Decode(r io.Reader) (image.Image, string, error)
- func DecodeBytes(b []byte) (image.Image, string, error)
- func Encoders() []string
- func PageSizes() []string
- func ParsePageSize(s string) (pdfkit.PageSize, error)
- func ReadersToPDF(rs []io.Reader, opt Options) ([]byte, error)
- func Redraw(pdf []byte, opt RedrawOptions) ([]byte, error)
- func ToPDF(images []image.Image, opt Options) ([]byte, error)
- func WriteTo(w io.Writer, images []image.Image, opt Options) error
- type Encoder
- type Options
- type Page
- type RasterOptions
- type RedrawOptions
- type ScannerEffect
Constants ¶
const DefaultMaxPixels = 100_000_000
DefaultMaxPixels is how large a picture Decode will read when no ceiling is given. A hundred megapixels is A4 at a thousand dots to the inch.
⛔ Said in bytes, because "a hundred megapixels" does not tell anybody what it permits: a decoded picture is four bytes a pixel, so this default lets a file of a few dozen bytes cost FOUR HUNDRED MEGABYTES. That is bounded, which is the property that matters and the one this package did not have — but a service taking pictures from strangers should set Options.MaxPixels to what its own pages actually need rather than inherit this.
Variables ¶
This section is empty.
Functions ¶
func Decode ¶
Decode reads a picture and says what format it turned out to be.
⛔ It reads the CONTENT. A file's name is a claim its bytes do not have to honour: a scanner that writes JPEG into "page.png" is ordinary, and a converter that believed the extension would hand the encoder the wrong picture or refuse a file it can read perfectly well. It refuses a picture of more than DefaultMaxPixels pixels, and it refuses it by its HEADER — see decodeWithin for why that distinction is the guard.
func DecodeBytes ¶
DecodeBytes is Decode over a slice.
func Encoders ¶
func Encoders() []string
Encoders names every format FromPDF can write, in a stable order.
func PageSizes ¶
func PageSizes() []string
PageSizes names every paper size this package knows, in a stable order.
func ParsePageSize ¶
ParsePageSize reads a paper size: a name such as "a4", optionally with "-landscape", or "WIDTHxHEIGHT" in points.
⛔ "" is NOT an error and NOT a default size: it means "size each page to its own picture", which is a different instruction from "use A4". A set of scans of different sizes must not all be forced onto one paper because the caller said nothing.
func ReadersToPDF ¶
ReadersToPDF decodes each reader and lays the pictures out as ToPDF does. The format of each is decided by its CONTENT, never by a name.
func Redraw ¶ added in v0.3.0
func Redraw(pdf []byte, opt RedrawOptions) ([]byte, error)
Redraw draws every page, changes the pixels, and lays the results back into a new PDF.
⛔ IT RASTERISES. What comes out has no text in it: no selection, no search, no copy, no screen reader, and a file many times larger. That is not a shortcoming of this implementation — changing the colours a page is PAINTED in means painting it — but it is a thing a caller has to have decided on purpose, which is why the function is named for what it does rather than for what it is for.
Where the operation can be done without redrawing, it belongs somewhere else: rotating, cropping, stamping and reordering are github.com/go-pdfkit/ops, and they keep the text.
Types ¶
type Encoder ¶
Encoder is a picture format this package can WRITE. Reading is wider than writing — WebP decodes and does not encode — so the two are separate tables rather than one list with exceptions in it.
type Options ¶
type Options struct {
// DPI is how many pixels of the picture go to an inch of paper. Zero means
// 72, at which one pixel is one point and a picture comes out at the size
// a PDF viewer calls 100%.
//
// It is what turns pixels into a page: a 2480x3508 scan at 300 is A4, and
// the same scan at 72 is a page a metre tall. There is no right answer this
// package could pick for you, only a sane default.
DPI float64
// Page, when set, is the page size every picture is placed on, and the
// picture is FITTED inside it: scaled down to fit if it is too big, centred
// either way, never cropped and never stretched out of proportion.
//
// When it is the zero value each page is sized to its own picture, which is
// what a set of scans of different sizes needs.
Page pdfkit.PageSize
// Margin is how much paper is left around a fitted picture, in points. It
// is only consulted when Page is set, because a page sized to its picture
// has no room to leave.
Margin float64
// Title goes in the document information dictionary.
Title string
// MaxPixels refuses a picture larger than this, so that a file cannot
// decide how much memory this package uses. Zero means a hundred million,
// which is A4 at a thousand dots to the inch and well past any scanner.
MaxPixels int
}
Options says how pictures become pages.
type Page ¶
type Page struct {
Number int // one-based, as the file numbers it
Format string // the format actually written
Data []byte
}
Page is one drawn page and the bytes it encoded to.
func FromPDF ¶
func FromPDF(pdf []byte, opt RasterOptions) ([]Page, error)
FromPDF draws the pages of a PDF and encodes each one.
func FromPDFReader ¶
func FromPDFReader(r io.Reader, opt RasterOptions) ([]Page, error)
FromPDFReader is FromPDF over a reader, for a file on disk.
type RasterOptions ¶
type RasterOptions struct {
// DPI is dots per inch. Zero means 150, which is legible on a screen and
// not so large that a hundred-page file fills a disk.
DPI float64
// Pages selects which pages to draw, one-based, in the order given. Nil
// means every page in the file's own order.
Pages []int
// Format is what to encode as: png, jpeg, gif, bmp or tiff. Empty means
// png, which is lossless and what a page of text should be.
Format string
// Quality is the JPEG quality, 1 to 100. Zero means 85. It is ignored by
// every other format.
Quality int
// Password opens an encrypted file.
Password string
// MaxPixels refuses a page that would come out larger than this. Zero
// leaves it to the renderer, whose own default is a little over A4 at 600
// dots to the inch.
MaxPixels int
}
RasterOptions says how pages become pictures.
type RedrawOptions ¶ added in v0.3.0
type RedrawOptions struct {
RasterOptions
// Title goes in the new document's information dictionary.
Title string
// Greyscale drops the colour.
Greyscale bool
// Invert turns light into dark. It is what a reader wants at night, and
// what a plotter wants of a dark-background figure.
Invert bool
// Brightness shifts every channel, from -1 (black) to +1 (white). Zero
// leaves it alone.
Brightness float64
// Contrast multiplies the distance from mid-grey: 1 leaves it alone, 2
// doubles it, 0.5 halves it. Zero means 1 — ⛔ a zero that meant "no
// contrast at all" would turn every page into a flat grey rectangle for
// every caller who set only the other fields.
Contrast float64
// Background is the colour the page is painted on. nil leaves the
// renderer's own white.
//
// ⛔ It is handed to the RENDERER rather than composited afterwards, and
// the difference is the whole option. A first version painted the colour
// under the finished raster — which does nothing at all, because the
// renderer has already filled the page with opaque white and there is no
// transparency left to show through. The option was documented, shipped,
// and had no effect; a screenshot found it, a byte count did not.
Background *color.RGBA
// Scanner, when set, makes the page look like it went through one.
Scanner *ScannerEffect
}
RedrawOptions says what to do to the pixels. Everything is off by default: the zero value redraws the pages unchanged, which is `rasterize-pdf`.
type ScannerEffect ¶ added in v0.3.0
type ScannerEffect struct {
// Skew is how far the sheet sits off square, in degrees. A tenth to a
// degree is what a careless hand produces.
Skew float64
// Noise is how much grain, from 0 to 1.
Noise float64
// Fade lightens the page, as a worn lamp does, from 0 to 1.
Fade float64
// Seed makes the grain reproducible. ⛔ Zero means a FIXED seed, not a
// random one: two runs over the same file must produce the same bytes, or
// nothing downstream can be compared, cached or checksummed — and an
// effect that is different every time is one nobody can test.
Seed uint64
}
ScannerEffect is the small damage a flatbed does: the sheet is never quite straight, the lamp is never quite even, and the sensor adds grain.