node-canvas

node-canvas is a Cairo-backed Canvas implementation for Node.js.node canvas是Node.jsCairo支持的画布实现。

Installation安装

$ npm install canvas

By default, binaries for macOS, Linux and Windows will be downloaded. 默认情况下,将下载macOS、Linux和Windows的二进制文件。If you want to build from source, use npm install --build-from-source and see the Compiling section below.如果要从源代码构建,请使用npm install --build-from-source,并参阅下面的编译部分。

The minimum version of Node.js required is 6.0.0.所需的Node.js的最低版本为6.0.0

Compiling编撰

If you don't have a supported OS or processor architecture, or you use --build-from-source, the module will be compiled on your system. 如果您没有受支持的操作系统或处理器体系结构,或者您使用--build-from-source,那么该模块将在您的系统上编译。This requires several dependencies, including Cairo and Pango.这需要几个依赖项,包括Cairo和Pango。

For detailed installation information, see the wiki. 有关详细的安装信息,请参阅维基One-line installation instructions for common OSes are below. 下面是常见操作系统的单线安装说明。Note that libgif/giflib, librsvg and libjpeg are optional and only required if you need GIF, SVG and JPEG support, respectively. Cairo v1.10.0 or later is required.请注意,libgif/giflib、librsvg和libjpeg是可选的,仅当您分别需要GIF、SVG和JPEG支持时才需要。需要Cairo v1.10.0或更高版本。

OS Command
OS X Using Homebrew:
brew install pkg-config cairo pango libpng jpeg giflib librsvg
Ubuntu sudo apt-get install build-essential libcairo2-dev libpango1.0-dev libjpeg-dev libgif-dev librsvg2-dev
Fedora sudo yum install gcc-c++ cairo-devel pango-devel libjpeg-turbo-devel giflib-devel
Solaris pkgin install cairo pango pkg-config xproto renderproto kbproto xextproto
OpenBSD doas pkg_add cairo pango png jpeg giflib
Windows See the wiki请参阅维基
Others See the wiki

Mac OS X v10.11+: If you have recently updated to Mac OS X v10.11+ and are experiencing trouble when compiling, run the following command: 如果您最近更新到Mac OS X v10.11+,并且在编译时遇到问题,请运行以下命令:xcode-select --install. Read more about the problem on Stack Overflow.阅读有关堆栈溢出问题的更多信息。 If you have xcode 10.0 or higher installed, in order to build from source you need NPM 6.4.1 or higher.如果您安装了xcode 10.0或更高版本,则为了从源代码构建,您需要NPM 6.4.1或更高。

Quick Example快速示例

const { createCanvas, loadImage } = require('canvas')
const canvas = createCanvas(200, 200)
const ctx = canvas.getContext('2d')

// Write "Awesome!"
ctx.font = '30px Impact'
ctx.rotate(0.1)
ctx.fillText('Awesome!', 50, 100)

// Draw line under text
var text = ctx.measureText('Awesome!')
ctx.strokeStyle = 'rgba(0,0,0,0.5)'
ctx.beginPath()
ctx.lineTo(50, 102)
ctx.lineTo(50 + text.width, 102)
ctx.stroke()

// Draw cat with lime helmet
loadImage('examples/images/lime-cat.jpg').then((image) => {
  ctx.drawImage(image, 50, 0, 70, 70)

  console.log('<img src="' + canvas.toDataURL() + '" />')
})

Upgrading from 1.x to 2.x从1x升级到2x

See the changelog for a guide to upgrading from 1.x to 2.x.有关从1x升级到2x的指南,请参阅更改日志

For version 1.x documentation, see the v1.x branch.有关1x版本的文档,请参阅v1.x分支

Documentation文档

This project is an implementation of the Web Canvas API and implements that API as closely as possible. 该项目是WebCanvas API的实现,并尽可能接近地实现API。For API documentation, please visit Mozilla Web Canvas API. 有关API文档,请访问Mozilla Web Canvas API(See Compatibility Status for the current API compliance.) (有关当前API合规性,请参阅兼容性状态。)All utility methods and non-standard APIs are documented below.下面介绍了所有实用程序方法和非标准API。

Utility methods

Non-standard APIs

createCanvas()

createCanvas(width: number, height: number, type?: 'PDF'|'SVG') => Canvas

Creates a Canvas instance. This method works in both Node.js and Web browsers, where there is no Canvas constructor. (See browser.js for the implementation that runs in browsers.)创建画布实例。这个方法在Node.js和Web浏览器中都有效,因为它们没有Canvas构造函数。(有关在浏览器中运行的实现,请参阅browser.js。)

const { createCanvas } = require('canvas')
const mycanvas = createCanvas(200, 200)
const myPDFcanvas = createCanvas(600, 800, 'pdf') // see "PDF Support" section

createImageData()

createImageData(width: number, height: number) => ImageData
createImageData(data: Uint8ClampedArray, width: number, height?: number) => ImageData
// for alternative pixel formats:
createImageData(data: Uint16Array, width: number, height?: number) => ImageData

Creates an ImageData instance. 创建ImageData实例。This method works in both Node.js and Web browsers.这种方法适用于Node.js和Web浏览器。

const { createImageData } = require('canvas')
const width = 20, height = 20
const arraySize = width * height * 4
const mydata = createImageData(new Uint8ClampedArray(arraySize), width)

loadImage()

loadImage() => Promise<Image>

Convenience method for loading images. 加载图像的便捷方法。This method works in both Node.js and Web browsers.这种方法适用于Node.js和Web浏览器。

const { loadImage } = require('canvas')
const myimg = loadImage('http://server.com/image.png')

myimg.then(() => {
  // do something with image
}).catch(err => {
  console.log('oh no!', err)
})

// or with async/await:
const myimg = await loadImage('http://server.com/image.png')
// do something with image

registerFont()

registerFont(path: string, { family: string, weight?: string, style?: string }) => void

To use a font file that is not installed as a system font, use registerFont() to register the font with Canvas. 要使用未安装为系统字体的字体文件,请使用registerFont()在画布上注册字体。This must be done before the Canvas is created.这必须在创建画布之前完成。

const { registerFont, createCanvas } = require('canvas')
registerFont('comicsans.ttf', { family: 'Comic Sans' })

const canvas = createCanvas(500, 500)
const ctx = canvas.getContext('2d')

ctx.font = '12px "Comic Sans"'
ctx.fillText('Everyone hates this font :(', 250, 10)

The second argument is an object with properties that resemble the CSS properties that are specified in @font-face rules. You must specify at least family. weight, and style are optional and default to 'normal'.第二个参数是一个对象,其属性类似于@font-face规则中指定的CSS属性。您必须至少指定familyweightstyle是可选的并且默认为'normal'

Image#src

img.src: string|Buffer

As in browsers, img.src can be set to a data: URI or a remote URL. 与在浏览器中一样,img.src可以设置为data:URI或远程URL。In addition, node-canvas allows setting src to a local file path or Buffer instance.此外,nodecanvas允许将src设置为本地文件路径或Buffer实例。

const { Image } = require('canvas')

// From a buffer:
fs.readFile('images/squid.png', (err, squid) => {
  if (err) throw err
  const img = new Image()
  img.onload = () => ctx.drawImage(img, 0, 0)
  img.onerror = err => { throw err }
  img.src = squid
})

// From a local file path:
const img = new Image()
img.onload = () => ctx.drawImage(img, 0, 0)
img.onerror = err => { throw err }
img.src = 'images/squid.png'

// From a remote URL:
img.src = 'http://picsum.photos/200/300'
// ... as above

// From a `data:` URI:
img.src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg=='
// ... as above

Note: In some cases, img.src= is currently synchronous. 注意:在某些情况下,img.src=当前是同步的。However, you should always use img.onload and img.onerror, as we intend to make img.src= always asynchronous as it is in browsers. 但是,您应该始终使用img.onloadimg.onerror,因为我们打算使img.src=始终像在浏览器中一样异步。See https://github.com/Automattic/node-canvas/issues/1007.请参阅https://github.com/Automattic/node-canvas/issues/1007

Image#dataMode

img.dataMode: number

Applies to JPEG images drawn to PDF canvases only.仅适用于绘制到PDF画布的JPEG图像。

Setting img.dataMode = Image.MODE_MIME or Image.MODE_MIME|Image.MODE_IMAGE enables MIME data tracking of images. 设置img.dataMode = Image.MODE_MIMEImage.MODE_MIME|Image.MODE_IMAGE可启用图像的MIME数据跟踪。When MIME data is tracked, PDF canvases can embed JPEGs directly into the output, rather than re-encoding into PNG. This can drastically reduce filesize and speed up rendering.当MIME数据被跟踪时,PDF画布可以将JPEG直接嵌入到输出中,而不是重新编码到PNG中。这可以大大减少文件大小并加快渲染速度。

const { Image, createCanvas } = require('canvas')
const canvas = createCanvas(w, h, 'pdf')
const img = new Image()
img.dataMode = Image.MODE_IMAGE // Only image data tracked
img.dataMode = Image.MODE_MIME // Only mime data tracked
img.dataMode = Image.MODE_MIME | Image.MODE_IMAGE // Both are tracked

If working with a non-PDF canvas, image data must be tracked; otherwise the output will be junk.如果使用非PDF画布,则必须跟踪图像数据;否则输出将是垃圾。

Enabling mime data tracking has no benefits (only a slow down) unless you are generating a PDF.启用mime数据跟踪没有任何好处(只是速度减慢),除非您正在生成PDF。

Canvas#toBuffer()

canvas.toBuffer((err: Error|null, result: Buffer) => void, mimeType?: string, config?: any) => void
canvas.toBuffer(mimeType?: string, config?: any) => Buffer

Creates a Buffer object representing the image contained in the canvas.创建表示画布中包含的图像的Buffer对象。

Return value返回值

If no callback is provided, a Buffer. If a callback is provided, none.如果没有提供回调,则为Buffer。如果提供回调,则不提供。

Examples示例

// Default: buf contains a PNG-encoded image默认值:buf包含PNG编码的图像
const buf = canvas.toBuffer()

// PNG-encoded, zlib compression level 3 for faster compression but bigger files, no filteringPNG编码,zlib压缩级别3,压缩速度更快,但文件更大,无需筛选
const buf2 = canvas.toBuffer('image/png', { compressionLevel: 3, filters: canvas.PNG_FILTER_NONE })

// JPEG-encoded, 50% qualityJPEG编码,50%质量
const buf3 = canvas.toBuffer('image/jpeg', { quality: 0.5 })

// Asynchronous PNG异步PNG
canvas.toBuffer((err, buf) => {
  if (err) throw err // encoding failed编码失败
  // buf is PNG-encoded image
})

canvas.toBuffer((err, buf) => {
  if (err) throw err // encoding failed
  // buf is JPEG-encoded image at 95% quality
}, 'image/jpeg', { quality: 0.95 })

// BGRA pixel values, native-endianBGRA像素值,原生端序
const buf4 = canvas.toBuffer('raw')
const { stride, width } = canvas
// In memory, this is `canvas.height * canvas.stride` bytes long.
// The top row of pixels, in BGRA order on little-endian hardware,在little-endian硬件上按BGRA顺序排列的最上面一行像素,
// left-to-right, is:从左到右为:
const topPixelsBGRALeftToRight = buf4.slice(0, width * 4)
// And the third row is:第三行是:
const row3 = buf4.slice(2 * stride, 2 * stride + width * 4)

// SVG and PDF canvases
const myCanvas = createCanvas(w, h, 'pdf')
myCanvas.toBuffer() // returns a buffer containing a PDF-encoded canvas返回包含PDF编码画布的缓冲区
// With optional metadata:使用可选元数据:
myCanvas.toBuffer('application/pdf', {
  title: 'my picture',
  keywords: 'node.js demo cairo',
  creationDate: new Date()
})

Canvas#createPNGStream()

canvas.createPNGStream(config?: any) => ReadableStream

Creates a ReadableStream that emits PNG-encoded data.创建一个ReadableStream,用于发出PNG编码的数据。

Examples示例

const fs = require('fs')
const out = fs.createWriteStream(__dirname + '/test.png')
const stream = canvas.createPNGStream()
stream.pipe(out)
out.on('finish', () =>  console.log('The PNG file was created.'))

To encode indexed PNGs from canvases with pixelFormat: 'A8' or 'A1', provide an options object:要使用pixelFormat: 'A8''A1'对画布中的索引PNG进行编码,请提供一个选项对象:

const palette = new Uint8ClampedArray([
  //r    g    b    a
    0,  50,  50, 255, // index 1
   10,  90,  90, 255, // index 2
  127, 127, 255, 255
  // ...
])
canvas.createPNGStream({
  palette: palette,
  backgroundIndex: 0 // optional, defaults to 0
})

Canvas#createJPEGStream()

canvas.createJPEGStream(config?: any) => ReadableStream

Creates a ReadableStream that emits JPEG-encoded data.创建一个ReadableStream,用于发送JPEG编码的数据。

Note: At the moment, createJPEGStream() is synchronous under the hood. That is, it runs in the main thread, not in the libuv threadpool.注意:目前,createJPEGStream()是同步的。也就是说,它在主线程中运行,而不是在libuv线程池中运行。

Examples示例

const fs = require('fs')
const out = fs.createWriteStream(__dirname + '/test.jpeg')
const stream = canvas.createJPEGStream()
stream.pipe(out)
out.on('finish', () =>  console.log('The JPEG file was created.'))

// Disable 2x2 chromaSubsampling for deeper colors and use a higher quality禁用2x2色度子采样以获得更深的颜色并使用更高的质量
const stream = canvas.createJPEGStream({
  quality: 0.95,
  chromaSubsampling: false
})

Canvas#createPDFStream()

canvas.createPDFStream(config?: any) => ReadableStream

Applies to PDF canvases only. Creates a ReadableStream that emits the encoded PDF. 仅适用于PDF画布。创建一个ReadableStream,用于发出编码的PDF。canvas.toBuffer() also produces an encoded PDF, but createPDFStream() can be used to reduce memory usage.也会生成编码的PDF,但createPDFStream()可以用于减少内存使用。

Canvas#toDataURL()

This is a standard API, but several non-standard calls are supported. The full list of supported calls is:这是一个标准的API,但支持几个非标准调用。支持的调用的完整列表为:

dataUrl = canvas.toDataURL() // defaults to PNG
dataUrl = canvas.toDataURL('image/png')
dataUrl = canvas.toDataURL('image/jpeg')
dataUrl = canvas.toDataURL('image/jpeg', quality) // quality from 0 to 1
canvas.toDataURL((err, png) => { }) // defaults to PNG
canvas.toDataURL('image/png', (err, png) => { })
canvas.toDataURL('image/jpeg', (err, jpeg) => { }) // sync JPEG is not supported
canvas.toDataURL('image/jpeg', {...opts}, (err, jpeg) => { }) // see Canvas#createJPEGStream for valid options
canvas.toDataURL('image/jpeg', quality, (err, jpeg) => { }) // spec-following; quality from 0 to 1

CanvasRenderingContext2D#patternQuality

context.patternQuality: 'fast'|'good'|'best'|'nearest'|'bilinear'

Defaults to 'good'. 默认为'good'Affects pattern (gradient, image, etc.) rendering quality.影响图案(渐变、图像等)渲染质量。

CanvasRenderingContext2D#quality

context.quality: 'fast'|'good'|'best'|'nearest'|'bilinear'

Defaults to 'good'. Like patternQuality, but applies to transformations affecting more than just patterns.默认为'good'。与patternQuality类似,但适用于影响图案的变换。

CanvasRenderingContext2D#textDrawingMode

context.textDrawingMode: 'path'|'glyph'

Defaults to 'path'. The effect depends on the canvas type:默认为'path'。效果取决于画布类型:

In glyph mode, ctx.strokeText() and ctx.fillText() behave the same (aside from using the stroke and fill style, respectively).在字形模式中,ctx.strokeText()ctx.fillText()的行为相同(除了分别使用笔划和填充样式之外)。

This property is tracked as part of the canvas state in save/restore.此属性在保存/还原时作为画布状态的一部分进行跟踪。

CanvasRenderingContext2D#globalCompositeOperation = 'saturate'

In addition to all of the standard global composite operations defined by the Canvas specification, the 'saturate' operation is also available.除了Canvas规范定义的所有标准全局合成操作之外,“饱和”操作也可用。

CanvasRenderingContext2D#antialias

context.antialias: 'default'|'none'|'gray'|'subpixel'

Sets the anti-aliasing mode.设置抗锯齿模式。

PDF Output Support

node-canvas can create PDF documents instead of images. Node画布可以创建PDF文档而不是图像。The canvas type must be set when creating the canvas as follows:创建画布时,必须按如下方式设置画布类型:

const canvas = createCanvas(200, 500, 'pdf')

An additional method .addPage() is then available to create multiple page PDFs:然后可以使用一个额外的方法.addPage()来创建多个页面PDF:

// On first page
ctx.font = '22px Helvetica'
ctx.fillText('Hello World', 50, 80)

ctx.addPage()
// Now on second page
ctx.font = '22px Helvetica'
ctx.fillText('Hello World 2', 50, 80)

canvas.toBuffer() // returns a PDF file
canvas.createPDFStream() // returns a ReadableStream that emits a PDF
// With optional document metadata (requires Cairo 1.16.0):
canvas.toBuffer('application/pdf', {
  title: 'my picture',
  keywords: 'node.js demo cairo',
  creationDate: new Date()
})

It is also possible to create pages with different sizes by passing width and height to the .addPage() method:还可以通过将widthheight传递给addPage()方法来创建不同大小的页面:

ctx.font = '22px Helvetica'
ctx.fillText('Hello World', 50, 80)
ctx.addPage(400, 800)

ctx.fillText('Hello World 2', 50, 80)

See also:

SVG Output Support

node-canvas can create SVG documents instead of images. Node画布可以创建SVG文档而不是图像。The canvas type must be set when creating the canvas as follows:创建画布时,必须按如下方式设置画布类型:

const canvas = createCanvas(200, 500, 'svg')
// Use the normal primitives.
fs.writeFileSync('out.svg', canvas.toBuffer())

SVG Image Support

If librsvg is available when node-canvas is installed, node-canvas can render SVG images to your canvas context. 如果在安装Node画布时librsvg可用,则Node画布可以将SVG图像呈现到画布上下文中。This currently works by rasterizing the SVG image (i.e. drawing an SVG image to an SVG canvas will not preserve the SVG data).目前,这是通过光栅化SVG图像来实现的(即,将SVG图像绘制到SVG画布将不会保留SVG数据)。

const img = new Image()
img.onload = () => ctx.drawImage(img, 0, 0)
img.onerror = err => { throw err }
img.src = './example.svg'

Image pixel formats (experimental)

node-canvas has experimental support for additional pixel formats, roughly following the Canvas color space proposal.

const canvas = createCanvas(200, 200)
const ctx = canvas.getContext('2d', { pixelFormat: 'A8' })

By default, canvases are created in the RGBA32 format, which corresponds to the native HTML Canvas behavior. Each pixel is 32 bits. The JavaScript APIs that involve pixel data (getImageData, putImageData) store the colors in the order {red, green, blue, alpha} without alpha pre-multiplication. (The C++ API stores the colors in the order {alpha, red, green, blue} in native-endian ordering, with alpha pre-multiplication.)

These additional pixel formats have experimental support:这些额外的像素格式提供了实验支持:

Notes and caveats:

Testing测试

First make sure you've built the latest version. 首先确保你已经建立了最新的版本。Get all the deps you need (see compiling above), and run:获取所需的所有dep(请参阅上面的编译),然后运行:

npm install --build-from-source

For visual tests: npm run test-server and point your browser to http://localhost:4000.对于视觉测试:npm run test-server并将浏览器指向http://localhost:4000

For unit tests: npm run test.对于单元测试:npm run test

Benchmarks

Benchmarks live in the benchmarks directory.基准位于benchmarks目录中。

Examples示例

Examples line in the examples directory. Most produce a png image of the same name, and others such as live-clock.js launch an HTTP server to be viewed in the browser.examples目录中的Examples行。大多数都会生成相同名称的png图像,而其他一些(如live-clock.js)则会启动HTTP服务器以在浏览器中查看。

Original Authors原创作者

License许可证

node-canvas

(The MIT License)

Copyright (c) 2010 LearnBoost, and contributors <dev@learnboost.com>

Copyright (c) 2014 Automattic, Inc and contributors <dev@automattic.com>

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:特此免费授予获得本软件副本和相关文档文件(“软件”)的任何人在不受限制的情况下处理本软件的权限,包括但不限于使用、复制、修改、合并、发布、分发、分许可和/或出售本软件副本的权利,并允许向其提供本软件的人员这样做,符合以下条件:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.上述版权声明和本许可声明应包含在软件的所有副本或重要部分中。

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.软件是“按原样”提供的,没有任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和不侵权的保证。在任何情况下,作者或版权持有人均不对因软件或软件的使用或其他交易而产生、产生或与之相关的任何索赔、损害赔偿或其他责任承担责任,无论是在合同诉讼、侵权诉讼还是其他诉讼中。

BMP parser

See license