手把手教你使用Express框架在Node服务端实现图片渲染
- 1.前言
- 2.node-canvas库
- 3.搭建node服务端环境
- 3.1 初始化项目
- 3.2 使用内置http模块创建服务
- 3.3 使用Express创建服务
- 4.服务端渲染图片
- 4.1 创建Express路由
- 4.2 绘制三角形
- 4.3 静态资源中间件
- 4.4 写入图片文件
- 4.5 渲染Echarts图表
1.前言
大家知道前端如何绘制出下面这个三角形吗?
相信很多人的答案都是canvas,使用canvas确实很容易就能实现上面的效果,代码如下:
<canvas id="canvas" width="400" height="400"></canvas>
<script>
var canvas = document.getElementById('canvas');// 获取canvas元素
var ctx = canvas.getContext('2d');// 获取绘图上下文
//绘制一个三角形
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(50, 100);
ctx.lineTo(100, 100);
ctx.stroke();
</script>
对canvas不了解的可以去看我的这篇文章,那你知道在Node.js服务端中如何使用canvas绘图吗,本文就来聊聊node服务端渲染图片。
2.node-canvas库
node中是没有DOM的,怎么绘图呢?这就得用到node-canvas这个库,来实现在node中进行canvas渲染。
不过,使用node-canvas这个库,不同的系统需要安装对应的依赖环境,如下图所示:
具体环境配置可以参考node-canvas官网
3.搭建node服务端环境
3.1 初始化项目
创建一个文件夹draw,执行npm init命令,该命令的作用就是初始化一个 package.json 文件,将项目变成一个npm项目:
npm init
接着可以一路回车下去,就会发现 package.json 文件已经创建好了。
- 安装node-canvas
安装node-canvas库,执行如下命令:
npm install canvas
- 安装nodemon
nodemon是一个流行的开发服务器,能够检测工作区代码的变化,并自动重启。执行下面命令进行安装 :
npm install nodemon --save-dev
这里将nodemon安装为开发依赖 devDependencies,因为仅仅只有在开发时才需要用到。同时可以配置start命令,package.json文件如下:
{
"name": "draw",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "nodemon server.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"nodemon": "^3.0.1"
},
"dependencies": {
"canvas": "^2.11.2"
}
}
3.2 使用内置http模块创建服务
在文件夹下新建一个server.js文件,代码如下:
//server.js
//1.导入 http 模块
const http = require('http');
const hostname = 'localhost';
const port = 3000;
//2.创建 HTTP 服务器
const server = http.createServer((req, res) => {
res.end('Hello World');
});
//3.监听端口, 启动服务
server.listen(port, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
运行npm start开启服务器:
npm start
浏览器打开http://localhost:3000/,可以看到如下效果:
直接用内置的 http 模块搭建服务器有个明显的缺点,就是没有专门的路由机制,即不能根据客户端不同URL及HTTP方法来返回相应内容。
因此,我们可以对上述代码进行改进,使用Express来开发Web服务器。
3.3 使用Express创建服务
Express是一个基于Node.js的快速、极简的流行Web开发框架,封装了很多功能,如路由和中间件等,可以更加方便的进行开发。
安装Express
npm install express
改写上述server.js代码,如下:
//server.js
//1.导入 express
const express = require('express');
const hostname = 'localhost';
const port = 3000;
//2.创建应用对象
const app = express();
//3.创建路由规则
app.get('/', (req, res) => {
res.send('Hello World');
});
//4.监听端口 启动服务
app.listen(port, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
运行npm start开启服务器,同样可以看到如下效果:
到这里,环境就基本搭建好了,下面正式开始绘图。
4.服务端渲染图片
4.1 创建Express路由
Express路由的官方定义:确定应用程序如何响应客户端对特定端点的请求,端点是 URI(路径)和HTTP请求方法(GET、POST 等)。
通俗来讲就是服务器根据客户端访问的端点选择相应处理逻辑的机制。一个路由的组成有请求方法,路径和回调函数,如下所示:
app.METHOD(PATH, HANDLER)
因此,我们可以创建一个用于绘图的路由:
app.get('/drawTriangle', (req, res) => {
//在这里写代码逻辑
});
4.2 绘制三角形
这里我们先来实现一下上面这个三角形的例子。
首先需要通过node-canvas提供的createCanvas方法创建画布,代码如下:
//引入createCanvas创建画布方法
const { createCanvas } = require("canvas");
//创建一个400 * 400的canvas
const canvas = createCanvas(400, 400);
其实node中绘图和前端绘图最主要的区别就在这里,node中需要通过node-canvas来创建canvas元素,接下来的绘图就和前端一致了:
...
//获取渲染上下文
const ctx = canvas.getContext("2d");
//绘制三角形
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(50, 100);
ctx.lineTo(100, 100);
ctx.stroke();
完成绘图后,接下来就是把绘制结果返回给前端。
4.3 静态资源中间件
Express内置了处理静态资源的中间件函数express.static,可以提供图片、CSS 文件、JS 文件这类静态文件的服务。
- 什么是中间件?
中间件本质就是一个回调函数,作用就是使用函数封装能够适用多个应用场景、可复用性良好的代码。
通过如下代码就可以设置一个静态文件中间件,指定当前文件夹下的public目录作为静态资源根目录:
app.use(express.static('./public'));
这样我们就可以访问public目录中的所有文件了,如:
http://localhost:3000/images/bg.png
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
4.4 写入图片文件
接下来我们只需要把绘制好的图片写入到public目录下即可,我们可以通过fs模块来实现。fs模块是Node.js中的内置模块,可以对计算机中的磁盘进行操作,如文件写入、读取、删除等。
文件写入可以使用fs.writeFileSync或fs.writeFile,两者区别:前者是同步写入,js主线程会等待其他线程的执行结果,然后再继续执行主线程的代码,效率较低;后者是异步写入,js主线程不会等待其他线程的执行结果,直接执行后续的主线程代码,效率较好。
这里我们使用fs.writeFile异步写入,其语法格式为:
fs.writeFile(file, data[, options], callback)
参数说明:
- file 文件名
- data 待写入的数据
- options 选项设置(可选)
- callback 写入回调
具体可以参考node官网。绘制的完整代码如下:
const express = require("express");
//引入创建画布方法
const { createCanvas } = require("canvas");
//引入fs模块
const fs = require('fs');
const hostname = "localhost";
const port = 3000;
const app = express();
//静态资源中间件的设置
app.use(express.static("./public"));
//创建绘图路由
app.get("/drawTriangle", (req, res) => {
//创建画布
const canvas = createCanvas(400, 400);
//获取渲染上下文
const ctx = canvas.getContext("2d");
//绘制三角形
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(50, 100);
ctx.lineTo(100, 100);
ctx.stroke();
//定义写入的目录和文件名
const imagePath = "./public/images";
const imageName = "triangle.png";
//如果不存在images图片目录就创建一个
if (!fs.existsSync(imagePath)) {
fs.mkdirSync(imagePath);
}
//将绘制结果写入指定文件,这里toBuffer创建一个Buffer表示画布中包含的图像对象,Buffer对象专门用来处理二进制数据
fs.writeFile(`${imagePath}/${imageName}`, canvas.toBuffer(), function (err) {
if (err) {
console.log("写入失败");
} else {
console.log("写入成功");
}
});
});
app.listen(port, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});
当请求http://localhost:3000/drawTriangle时,就会进行三角形的绘制,并写入public静态资源目录:
然后浏览器就可以访问这个图片,如下所示:
到这你以为结束了吗?绘图怎么能少得了Echarts呢,下面就来讲讲Echarts的渲染。
4.5 渲染Echarts图表
安装echarts库
npm install echarts
引入echarts库
const echarts = require("echarts");
渲染Echarts图表,代码如下:
//server.js
...
const options = {
title: {
text: "第一个 ECharts 实例",
},
tooltip: {},
legend: {
data: ["销量"],
},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
},
yAxis: {},
series: [
{
name: "销量",
type: "bar",
data: [5, 20, 36, 10, 10, 20],
},
],
};
app.get("/drawChart", (req, res) => {
const canvas = createCanvas(400, 400);
const imagePath = "./public/images";
const imageName = "chart.png";
//初始化echarts,使用创建的canvas作为初始化容器
const chart = echarts.init(canvas);
chart.setOption(options);
//写入文件,chart.getDom()即获取绘制好的canvas
fs.writeFile(`${imagePath}/${imageName}`, chart.getDom().toBuffer(), function (err) {
if (err) {
console.log("写入失败");
} else {
console.log("写入成功");
}
});
});
...
当请求http://localhost:3000/drawTriangle时,就会进行图表的渲染:
浏览器访问:
好了,以上就是本文的全部内容,如有问题,欢迎指出,如有帮助,点个赞,鼓励一下作者吧。