@@ -80,9 +80,11 @@ loadImage('examples/images/lime-cat.jpg').then((image) => {
8080})
8181```
8282
83- ## Non-Standard API
83+ ## Non-Standard APIs
8484
85- node-canvas extends the canvas API to provide interfacing with node, for example streaming PNG data, converting to a ` Buffer ` instance, etc. Among the interfacing API, in some cases the drawing API has been extended for SSJS image manipulation / creation usage, however keep in mind these additions may fail to render properly within browsers.
85+ node-canvas implements the [ HTML Canvas API] ( https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API ) as closely as possible.
86+ (See [ Compatibility Status] ( https://github.com/Automattic/node-canvas/wiki/Compatibility-Status )
87+ for the current API compliance.) All non-standard APIs are documented below.
8688
8789### Image#src=Buffer
8890
@@ -125,84 +127,147 @@ img.dataMode = Image.MODE_MIME | Image.MODE_IMAGE; // Both are tracked
125127
126128If image data is not tracked, and the Image is drawn to an image rather than a PDF canvas, the output will be junk. Enabling mime data tracking has no benefits (only a slow down) unless you are generating a PDF.
127129
128- ### Canvas#pngStream(options )
130+ ### Canvas#toBuffer( )
129131
130- To create a ` PNGStream ` simply call ` canvas.pngStream() ` , and the stream will start to emit _ data_ events, emitting _ end_ when the data stream ends. If an exception occurs the _ error_ event is emitted.
132+ Creates a [ ` Buffer ` ] ( https://nodejs.org/api/buffer.html ) object representing the
133+ image contained in the canvas.
134+
135+ > ` canvas.toBuffer((err: Error|null, result: Buffer) => void[, mimeType[, config]]) => void `
136+ > ` canvas.toBuffer([mimeType[, config]]) => Buffer `
137+
138+ * ** callback** If provided, the buffer will be provided in the callback instead
139+ of being returned by the function. Invoked with an error as the first argument
140+ if encoding failed, or the resulting buffer as the second argument if it
141+ succeeded. Not supported for mimeType ` raw ` or for PDF or SVG canvases (there
142+ is no async work to do in those cases). * Note* : Currently the callback
143+ function is invoked synchronously for ` image/jpeg ` .
144+ * ** mimeType** A string indicating the image format. Valid options are ` image/png ` ,
145+ ` image/jpeg ` (if node-canvas was built with JPEG support) and ` raw ` (unencoded
146+ ARGB32 data in native-endian byte order, top-to-bottom). Defaults to
147+ ` image/png ` . If the canvas is a PDF or SVG canvas, this argument is ignored
148+ and a PDF or SVG is returend always.
149+ * ** config**
150+ * For ` image/jpeg ` an object specifying the quality (0 to 1), if progressive
151+ compression should be used and/or if chroma subsampling should be used:
152+ ` {quality: 0.75, progressive: false, chromaSubsampling: true} ` . All
153+ properties are optional.
154+ * For ` image/png ` , an object specifying the ZLIB compression level (between 0
155+ and 9), the compression filter(s), the palette (indexed PNGs only) and/or
156+ the background palette index (indexed PNGs only):
157+ ` {compressionLevel: 6, filter: Canvas.PNG_ALL_FILTERS, palette: undefined, backgroundIndex: 0} ` .
158+ All properties are optional.
159+
160+ ** Return value**
161+
162+ If no callback is provided, a [ ` Buffer ` ] ( https://nodejs.org/api/buffer.html ) .
163+ If a callback is provided, none.
164+
165+ #### Examples
131166
132167``` javascript
133- var fs = require (' fs' )
134- , out = fs .createWriteStream (__dirname + ' /text.png' )
135- , stream = canvas .pngStream ();
168+ // Default: buf contains a PNG-encoded image
169+ const buf = canvas .toBuffer ()
136170
137- stream .pipe (out);
171+ // PNG-encoded, zlib compression level 3 for faster compression but bigger files, no filtering
172+ const buf2 = canvas .toBuffer (' image/png' , {compressionLevel: 3 , filter: Canvas .PNG_FILTER_NONE })
138173
139- out .on (' finish' , function (){
140- console .log (' The PNG file was created.' );
141- });
174+ // JPEG-encoded, 50% quality
175+ const buf3 = canvas .toBuffer (' image/jpeg' , {quality: 0.5 })
176+
177+ // Asynchronous PNG
178+ canvas .toBuffer ((err , buf ) => {
179+ if (err) throw err; // encoding failed
180+ // buf is PNG-encoded image
181+ })
182+
183+ canvas .toBuffer ((err , buf ) => {
184+ if (err) throw err; // encoding failed
185+ // buf is JPEG-encoded image at 95% quality
186+ // Note that this callback is currently called synchronously.
187+ }, ' image/jpeg' , {quality: 0.95 })
188+
189+ // ARGB32 pixel values, native-endian
190+ const buf4 = canvas .toBuffer (' raw' )
191+ const {stride , width } = canvas
192+ // In memory, this is `canvas.height * canvas.stride` bytes long.
193+ // The top row of pixels, in ARGB order, left-to-right, is:
194+ const topPixelsARGBLeftToRight = buf4 .slice (0 , width * 4 )
195+ // And the third row is:
196+ const row3 = buf4 .slice (2 * stride, 2 * stride + width * 4 )
197+
198+ // SVG and PDF canvases ignore the mimeType argument
199+ const myCanvas = createCanvas (w, h, ' pdf' )
200+ myCanvas .toBuffer () // returns a buffer containing a PDF-encoded canvas
201+ ```
202+
203+ ### Canvas#pngStream(options)
204+
205+ Creates a [ ` ReadableStream ` ] ( https://nodejs.org/api/stream.html#stream_class_stream_readable )
206+ that emits PNG-encoded data.
207+
208+ > ` canvas.pngStream([config]) => ReadableStream `
209+
210+ * ` config ` An object specifying the ZLIB compression level (between 0 and 9),
211+ the compression filter(s), the palette (indexed PNGs only) and/or the
212+ background palette index (indexed PNGs only):
213+ ` {compressionLevel: 6, filter: Canvas.PNG_ALL_FILTERS, palette: undefined, backgroundIndex: 0} ` .
214+ All properties are optional.
215+
216+ #### Examples
217+
218+ ``` javascript
219+ const fs = require (' fs' )
220+ const out = fs .createWriteStream (__dirname + ' /test.png' )
221+ const stream = canvas .pngStream ()
222+ stream .pipe (out)
223+ out .on (' finish' , () => console .log (' The PNG file was created.' ))
142224```
143225
144226To encode indexed PNGs from canvases with ` pixelFormat: 'A8' ` or ` 'A1' ` , provide an options object:
145227
146228``` js
147- var palette = new Uint8ClampedArray ([
229+ const palette = new Uint8ClampedArray ([
148230 // r g b a
149231 0 , 50 , 50 , 255 , // index 1
150232 10 , 90 , 90 , 255 , // index 2
151233 127 , 127 , 255 , 255
152234 // ...
153- ]);
235+ ])
154236canvas .pngStream ({
155237 palette: palette,
156238 backgroundIndex: 0 // optional, defaults to 0
157239})
158240```
159241
160- ### Canvas#jpegStream() and Canvas#syncJPEGStream()
242+ ### Canvas#jpegStream()
161243
162- You can likewise create a ` JPEGStream ` by calling ` canvas.jpegStream() ` with
163- some optional parameters; functionality is otherwise identical to
164- ` pngStream() ` . See ` examples/crop.js ` for an example.
244+ Creates a [ ` ReadableStream ` ] ( https://nodejs.org/api/stream.html#stream_class_stream_readable )
245+ that emits JPEG-encoded data.
165246
166- _ Note: At the moment, ` jpegStream() ` is the same as ` syncJPEGStream() ` , both
167- are synchronous _
247+ _ Note: At the moment, ` jpegStream() ` is synchronous under the hood. That is, it
248+ runs in the main thread, not in the libuv threadpool. _
168249
169- ``` javascript
170- var stream = canvas .jpegStream ({
171- bufsize: 4096 // output buffer size in bytes, default: 4096
172- , quality: 75 // JPEG quality (0-100) default: 75
173- , progressive: false // true for progressive compression, default: false
174- , chromaSubsampling: true // false to disable 2x2 subsampling of the chroma components, default: true
175- });
176- ```
250+ > ` canvas.pngStream([config]) => ReadableStream `
177251
178- ### Canvas#toBuffer()
252+ * ` config ` an object specifying the quality (0 to 1), if progressive compression
253+ should be used and/or if chroma subsampling should be used:
254+ ` {quality: 0.75, progressive: false, chromaSubsampling: true} ` . All properties
255+ are optional.
179256
180- A call to ` Canvas#toBuffer() ` will return a node ` Buffer ` instance containing image data.
257+ #### Examples
181258
182259``` javascript
183- // PNG Buffer, default settings
184- var buf = canvas .toBuffer ();
185-
186- // PNG Buffer, zlib compression level 3 (from 0-9), faster but bigger
187- var buf2 = canvas .toBuffer (undefined , 3 , canvas .PNG_FILTER_NONE );
188-
189- // ARGB32 Buffer, native-endian
190- var buf3 = canvas .toBuffer (' raw' );
191- var stride = canvas .stride ;
192- // In memory, this is `canvas.height * canvas.stride` bytes long.
193- // The top row of pixels, in ARGB order, left-to-right, is:
194- var topPixelsARGBLeftToRight = buf3 .slice (0 , canvas .width * 4 );
195- var row3 = buf3 .slice (2 * canvas .stride , 2 * canvas .stride + canvas .width * 4 );
196- ```
197-
198- ### Canvas#toBuffer() async
199-
200- Optionally we may pass a callback function to ` Canvas#toBuffer() ` , and this process will be performed asynchronously, and will ` callback(err, buf) ` .
201-
202- ``` javascript
203- canvas .toBuffer (function (err , buf ){
204-
205- });
260+ const fs = require (' fs' )
261+ const out = fs .createWriteStream (__dirname + ' /test.jpeg' )
262+ const stream = canvas .jpegStream ()
263+ stream .pipe (out)
264+ out .on (' finish' , () => console .log (' The JPEG file was created.' ))
265+
266+ // Disable 2x2 chromaSubsampling for deeper colors and use a higher quality
267+ const stream = canvas .jpegStream ({
268+ quality: 95 ,
269+ chromaSubsampling: false
270+ })
206271```
207272
208273### Canvas#toDataURL() sync and async
0 commit comments