node-canvas

Test NPM version

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

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.这需要几个依赖关系,包括开罗和Pango。

For detailed installation information, see the wiki. 有关详细安装信息,请参阅wikiOne-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. 请注意,libgif/giflib、librsvg和libjpeg是可选的,仅当您分别需要GIF、SVG和JPEG支持时才需要。Cairo v1.10.0 or later is required.需要Cairo v1.10.0或更高版本。

OS Command
OS X Using Homebrew:
brew install pkg-config cairo pango libpng jpeg giflib librsvg pixman
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: xcode-select --install. 如果您最近更新到Mac OS X v10.11+,并且在编译时遇到问题,请运行以下命令:xcode-select --installRead more about the problem on Stack Overflow. 阅读有关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. 该项目是Web Canvas 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非标准API

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. 此方法在Node.js和Web浏览器中都有效,因为没有Canvas构造函数。(See browser.js for the implementation that runs in browsers.)(有关在浏览器中运行的实现,请参阅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()向Canvas注册字体。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. 第二个参数是一个具有类似于@font-face规则中指定的CSS属性的属性的对象。You must specify at least family. 必须至少指定familyweight, and style are optional and default to 'normal'.weightstyle是可选的,默认为'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.此外,节点画布允许将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 #1007.请参阅#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. 当跟踪MIME数据时,PDF画布可以将JPEG直接嵌入到输出中,而不是重新编码为PNG。This can drastically reduce filesize and speed up rendering.这可以大大减少文件大小并加快渲染速度。

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.除非您正在生成PDF,否则启用mime数据跟踪没有任何好处(只会降低速度)。

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. 如果未提供回调,则为BufferIf a callback is provided, none.如果提供了回调,则为none。

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 imagebuf是PNG编码图像
})

canvas.toBuffer((err, buf) => {
  if (err) throw err // encoding failed编码失败
  // buf is JPEG-encoded image at 95% qualitybuf是质量为95%的JPEG编码图像
}, '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.在内存中,这是`canvas.height * canvas.stride`字节长。
// The top row of pixels, in BGRA order on little-endian hardware,在小端硬件上,
// 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 canvasesSVG和PDF画布
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.创建发出PNG编码数据的ReadableStream

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.创建发出JPEG编码数据的ReadableStream

Note: At the moment, createJPEGStream() is synchronous under the hood. 注意:目前,createJPEGStream()是同步的。That is, it runs in the main thread, not in the libuv threadpool.也就是说,它在主线程中运行,而不是在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. 仅适用于PDF画布。Creates a ReadableStream that emits the encoded PDF. 创建发出编码PDF的ReadableStreamcanvas.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. 这是一个标准API,但支持几个非标准调用。The full list of supported calls is:支持的呼叫的完整列表为:

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'. 默认为'good'Like patternQuality, but applies to transformations affecting more than just patterns.patternQuality类似,但适用于不仅影响模式的变换。

CanvasRenderingContext2D#textDrawingMode

context.textDrawingMode: 'path'|'glyph'

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

In glyph mode, ctx.strokeText() and ctx.fillText() behave the same (aside from using the stroke and fill style, respectively).glyph模式中,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规范定义的所有标准全局复合操作之外,'saturate'操作也可用。

CanvasRenderingContext2D#antialias

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

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

PDF Output SupportPDF输出支持

node-canvas can create PDF documents instead of images. 节点画布可以创建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返回发出PDF的ReadableStream
// With optional document metadata (requires Cairo 1.16.0):使用可选文档元数据(要求开罗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 SupportSVG输出支持

node-canvas can create SVG documents instead of images. 节点画布可以创建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 SupportSVG图像支持

If librsvg is available when node-canvas is installed, node-canvas can render SVG images to your canvas context. 如果在安装节点canvas时librsvg可用,则节点canva可以将SVG图像呈现到您的canvas上下文中。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.节点canvas对其他像素格式有实验性支持,大致遵循canvas颜色空间建议

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. 默认情况下,画布以RGBA32格式创建,这与本地HTML画布行为相对应。Each pixel is 32 bits. 每个像素为32位。The JavaScript APIs that involve pixel data (getImageData, putImageData) store the colors in the order {red, green, blue, alpha} without alpha pre-multiplication. 涉及像素数据(getImageDataputImageData)的JavaScript API按{red, green, blue, alpha}的顺序存储颜色,无需alpha预乘法。(The C++ API stores the colors in the order {alpha, red, green, blue} in native-endian ordering, with alpha pre-multiplication.)(C++API以本机endian顺序按{alpha, red, green, blue}的顺序存储颜色,并使用alpha预乘法。)

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. 示例目录中的examples行。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.大多数都会生成同名的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