Skip to content

Commit d1c0233

Browse files
committed
Update to Canvas 2.0
1 parent 7acabe6 commit d1c0233

File tree

4 files changed

+161
-3
lines changed

4 files changed

+161
-3
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
./node_modules
1+
node_modules
22
package-lock.json

README.md

Lines changed: 137 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,137 @@
1-
# lambda-node-canvas
2-
AWS Lambda blueprint for generating and manipulating graphics using node-canvas, a Cairo backed Canvas implementation for NodeJS by @Automattic.
1+
# Changes on this repository
2+
3+
Due to the size of dependencies, i.e. node_modules folder, it is no longer available to edit any serverless app based on this blueprint using AWS Lambda inline editor with node-canvas version 2.0+. So, I update this repository as resource space for those who would like to use node-canvas in their AWS Lambda functions.
4+
5+
In order to use node-canvas on AWS Lambda, there is an official guide from @Automattic. For native dependencies like libcairo.so.2 and others, you may use the files I uploaded to this repostory.
6+
7+
# Getting node-canvas works on AWS Lambda
8+
9+
Node canvas is a Cairo backed Canvas implementation for NodeJS by @Automattic. Following is the snapshot of Installation Guide from [official wiki](https://github.com/Automattic/node-canvas) last updated on Sep 3, 2018.
10+
11+
**Canvas 2.0 and 1.6 works out-of-the-box on AWS Lambda thanks to prebuilds. However, you must build your Lambda ZIP file on Linux (or a Linux Docker container) so that the correct prebuilt binary is included.** See https://github.com/Automattic/node-canvas/issues/1231 for more info.
12+
13+
The below instructions can be used for older versions or custom builds.
14+
15+
---
16+
17+
Lambda doesn't have the required libraries installed by default, but it can load them from either the `./` or `./lib` directories in your packaged function.
18+
19+
Create an EC2 VM from the [the Lambda AMI](https://docs.aws.amazon.com/lambda/latest/dg/current-supported-versions.html), we'll use this to build canvas and grab compatible libraries.
20+
21+
Install Node and development tools:
22+
23+
```bash
24+
sudo yum groupinstall "Development Tools" -y
25+
curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | bash
26+
27+
# Exit SSH session and reopen here to make nvm available
28+
29+
# Node 6.10:
30+
nvm install 6.10
31+
# Or Node 8.10:
32+
nvm install 8.10
33+
```
34+
35+
Install node-canvas as you normally would on Linux:
36+
37+
```bash
38+
sudo yum install cairo-devel libjpeg-turbo-devel giflib-devel pango-devel -y
39+
npm install canvas@next
40+
```
41+
42+
Then copy the system libraries from `/usr/lib64/` into a `./lib/` subdirectory for your Lambda function:
43+
44+
```
45+
mkdir lib
46+
cp /usr/lib64/{libpng12.so.0,libjpeg.so.62,libpixman-1.so.0,libfreetype.so.6,\
47+
libcairo.so.2,libpango-1.0.so.0,libpangocairo-1.0.so.0,libpangoft2-1.0.so.0} lib/
48+
```
49+
50+
At this point you can package up the `node_modules` and `lib` directories and download them to your local machine. The `node_modules/canvas/build/Release/canvas.node` library has been built for the Lambda architecture, so don't overwrite it by rebuilding the canvas package on your local machine.
51+
52+
Then you can add an `index.js` handler to test Canvas with:
53+
54+
```js
55+
let
56+
{createCanvas} = require("canvas");
57+
58+
function hello(event, context, callback) {
59+
let
60+
canvas = createCanvas(200, 200),
61+
ctx = canvas.getContext('2d');
62+
63+
// Write "Awesome!"
64+
ctx.font = '30px Impact';
65+
ctx.rotate(0.1);
66+
ctx.fillText('Awesome!', 50, 100);
67+
68+
// Draw line under text
69+
let
70+
text = ctx.measureText('Awesome!');
71+
ctx.strokeStyle = 'rgba(0,0,0,0.5)';
72+
ctx.beginPath();
73+
ctx.lineTo(50, 102);
74+
ctx.lineTo(50 + text.width, 102);
75+
ctx.stroke();
76+
77+
callback(null, '<img src="' + canvas.toDataURL() + '" />');
78+
}
79+
80+
module.exports = {hello};
81+
```
82+
83+
You can now zip up this function and manually deploy it to Lambda (just set Node to 6.10 and the handler to `index.hello`), or you can deploy it using [Serverless](https://serverless.com/). For Serverless, add a `serverless.yml` file to the root of your project:
84+
85+
```
86+
service: canvas-test
87+
88+
provider:
89+
name: aws
90+
runtime: nodejs6.10
91+
stage: dev
92+
region: us-east-1
93+
memorySize: 128
94+
timeout: 10
95+
96+
functions:
97+
hello:
98+
handler: index.hello
99+
```
100+
101+
The resulting project structure:
102+
103+
```
104+
├── index.js
105+
├── lib
106+
│ ├── libcairo.so.2
107+
│ ├── libfreetype.so.6
108+
│ ├── libjpeg.so.62
109+
│ ├── libpango-1.0.so.0
110+
│ ├── libpangocairo-1.0.so.0
111+
│ ├── libpangoft2-1.0.so.0
112+
│ ├── libpixman-1.so.0
113+
│ └── libpng12.so.0
114+
├── node_modules
115+
│ ├── canvas
116+
│ ....
117+
│ └── nan
118+
│ ....
119+
└── serverless.yml
120+
```
121+
122+
Call `serverless deploy` to deploy it to Lambda, and `serverless invoke --function hello` to run it, and you should get back the HTML for this successful result:
123+
124+
![download](https://user-images.githubusercontent.com/1921411/36058675-c8f79756-0e8b-11e8-8b85-ea7ac4e3d150.png)
125+
126+
## Using newer versions of libcairo
127+
128+
The version of Amazon Linux that Lambda uses includes libcairo v1.12, which produces noticeably poor results when downscaling images with `drawImage()`. This was fixed in Cairo v1.14. You can use the install instructions for EC2 ([[Installation - Amazon-Linux-AMI-(EC2)]]) to build libcairo 1.14 and libpixman 0.34 from source, and replace the `libcairo.so.2` and `libpixman-1.so.0` binaries in your Lambda's `lib` directory with the resulting libraries (you can find those built libraries in `/usr/local/lib`).
129+
130+
However, due to the ordering of the directories in Lambda's `LD_LIBRARY_PATH` (`/var/lang/lib:/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib`) the operating system's included libcairo and libpixman will be used instead of the copies in your Lambda's `lib` directory. To fix this you need to set LDFLAGS during canvas installation:
131+
132+
```bash
133+
export LDFLAGS=-Wl,-rpath=/var/task/lib
134+
npm install canvas@next
135+
```
136+
137+
This will set the RPATH flags in the built `canvas.node` library to look for libraries in `/var/task/lib` first (your Lambda's bundled `lib` directory). Update the copy of `canvas.node` in your Lambda's `lib` directory with this newly-built version.

index.js

Whitespace-only changes.

package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "lambda-node-canvas",
3+
"version": "1.0.0",
4+
"description": "AWS Lambda blueprint for generating and manipulating graphics using node-canvas, a Cairo backed Canvas implementation for NodeJS by @Automattic.",
5+
"main": "index.js",
6+
"scripts": {
7+
"test": "echo \"Error: no test specified\" && exit 1"
8+
},
9+
"repository": {
10+
"type": "git",
11+
"url": "git+https://github.com/charoitel/lambda-node-canvas.git"
12+
},
13+
"keywords": [],
14+
"author": "",
15+
"license": "ISC",
16+
"bugs": {
17+
"url": "https://github.com/charoitel/lambda-node-canvas/issues"
18+
},
19+
"homepage": "https://github.com/charoitel/lambda-node-canvas#readme",
20+
"dependencies": {
21+
"canvas": "^2.6.1"
22+
}
23+
}

0 commit comments

Comments
 (0)