In the time of a cup of tea, I will show you how to use the Express framework to render images on the server side.

Directory

  • Preface
  • node-canvas library
  • Build node server environment
    • Initialize project
    • Create a service using the built-in http module
    • Create a service using Express
  • Server-side rendering of images
    • Create Express route
    • draw triangle
    • Static resource middleware
    • Write image file
    • Rendering Echarts charts
  • Conclusion

Foreword

Hello everyone, my name is Nanmu Yuanyuan, and I am passionate about sharing interesting and practical articles. Does anyone know how to draw the triangle below on the front end?

I believe many people’s answer is canvas. It is indeed easy to achieve the above effect using canvas. The code is as follows:

<canvas id="canvas" width="400" height="400"></canvas>
<script>
    var canvas = document.getElementById('canvas'); // Get the canvas element
    var ctx = canvas.getContext('2d');//Get the drawing context
    //Draw a triangle
    ctx.moveTo(100, 100);
    ctx.lineTo(200, 200);
    ctx.lineTo(50, 100);
    ctx.lineTo(100, 100);
    ctx.stroke();
</script>

If you don’t know about canvas, you can read my article. Do you know how to implement it on the Node.js server? This article will talk about drawing in node.

node-canvas library

There is no DOM in node, how to draw? This requires the use of the node-canvas library to implement canvas rendering in node.

However, to use the node-canvas library, different systems need to install corresponding dependency environments, as shown in the following figure:

For specific environment configuration, please refer to the node-canvas official website.

Build a node server environment

Initialization project

Create a folder draw and execute the npm init command. The function of this command is to initialize a package.json file and turn the project into an npm project:

npm init

Then you can press Enter all the way and you will find that the package.json file has been created.

  • Install node-canvas

Install the node-canvas library and execute the following command:

npm install canvas
  • Install nodemon

nodemon is a popular development server that detects changes to workspace code and automatically restarts it. Execute the following command to install:

npm install nodemon --save-dev

Here nodemon is installed as a development dependency devDependencies, because it is only needed during development. At the same time, you can configure the start command. The package.json file is as follows:

{<!-- -->
  "name": "draw",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {<!-- -->
    "start": "nodemon server.js",
    "test": "echo "Error: no test specified" & amp; & amp; exit 1"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {<!-- -->
    "nodemon": "^3.0.1"
  },
  "dependencies": {<!-- -->
    "canvas": "^2.11.2"
  }
}

Create services using the built-in http module

Create a new server.js file in the folder with the following code:

//server.js
//1.Import http module
const http = require('http');

const hostname = 'localhost';
const port = 3000;
//2. Create HTTP server
const server = http.createServer((req, res) => {<!-- -->
  res.end('Hello World');
});
//3. Listen to the port and start the service
server.listen(port, () => {<!-- -->
  console.log(`Server running at http://${<!-- -->hostname}:${<!-- -->port}/`);
});

Run npm start to start the server:

npm start

Open http://localhost:3000/ in the browser and you can see the following effect:

There is an obvious disadvantage of directly using the built-in http module to build a server, that is, there is no special routing mechanism, that is, it cannot return corresponding content according to different URLs and HTTP methods of the client. Therefore, we can improve the above code and use Express to develop a web server.

Create a service using Express

Express is a fast, minimalist and popular web development framework based on Node.js. It encapsulates many functions, such as routing and middleware, making development more convenient.

Install Express

npm install express

Rewrite the above server.js code as follows:

//server.js
//1.Import express
const express = require('express');

const hostname = 'localhost';
const port = 3000;
//2. Create application object
const app = express();
//3. Create routing rules
app.get('/', (req, res) => {<!-- -->
  res.send('Hello World');
});
//4. Listen to the port and start the service
app.listen(port, () => {<!-- -->
  console.log(`Server running at http://${<!-- -->hostname}:${<!-- -->port}/`);
});

Run npm start to start the server, and you can also see the following effect:


At this point, the environment is basically set up, and drawing is officially started.

Server-side rendering of images

Create Express route

The official definition of Express routing: Determines how an application responds to client requests for a specific endpoint, which is a URI (path) and HTTP request method (GET, POST, etc.). In layman’s terms, it is a mechanism for the server to select corresponding processing logic based on the endpoint accessed by the client. A route consists of request method, path and callback function, as shown below:

app.METHOD(PATH, HANDLER)

Therefore, we can create a route for drawing:

app.get('/drawTriangle', (req, res) => {<!-- -->
  //Write code logic here
});

Draw a triangle

Here we first implement the triangle example above.

First, you need to create a canvas through the createCanvas method provided by node-canvas. The code is as follows:

//Introduce createCanvas to create a canvas method
const {<!-- --> createCanvas } = require("canvas");
//Create a 400 * 400 canvas
const canvas = createCanvas(400, 400);

In fact, the main difference between drawing in node and front-end drawing is here. In node, node-canvas is needed to create the canvas element, and the subsequent drawing is consistent with the front-end:

...
//Get rendering context
const ctx = canvas.getContext("2d");
//Draw triangle
ctx.moveTo(100, 100);
ctx.lineTo(200, 200);
ctx.lineTo(50, 100);
ctx.lineTo(100, 100);
ctx.stroke();

After completing the drawing, the drawing results need to be returned to the front end.

Static resource middleware

Express has built-in middleware function express.static for processing static resources, which can provide services for static files such as images, CSS files, and JS files.

  • What is middleware?

Middleware is essentially a callback function. Its function is to use functions to encapsulate code that can be applied to multiple application scenarios and has good reusability.

Through the following code, you can set up a static file middleware and specify the public directory under the current folder as the static resource root directory:

app.use(express.static('./public'));

In this way we can access all files in the public directory, such as:

http://localhost:3000/images/bg.png
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js

Write image file

Next, we only need to write the drawn pictures to the public directory. We can do this through the fs module. The fs module is a built-in module in Node.js, which can operate on the disk in the computer, such as file writing, reading, deletion, etc.

File writing can use fs.writeFileSync or fs.writeFile. The difference between the two is: the former is synchronous writing, the js main thread will wait for the execution results of other threads, and then continue to execute the main thread’s code, which is less efficient; the latter is Asynchronous writing, the js main thread will not wait for the execution results of other threads, and directly execute the subsequent main thread code, which is more efficient.

Here we use fs.writeFile to write asynchronously, and its syntax format is:

fs.writeFile(file, data[, options], callback)

Parameter Description:

  • file file name
  • data data to be written
  • options option settings (optional)
  • callback write callback

For detailed parameters of fs.writeFile, please refer to the node official website. The complete code for drawing a triangle is as follows:

const express = require("express");
//Introduce the method of creating canvas
const {<!-- --> createCanvas } = require("canvas");
//Introduce fs module
const fs = require('fs');

const hostname = "localhost";
const port = 3000;

const app = express();
//Static resource middleware settings
app.use(express.static("./public"));

//Create drawing route
app.get("/drawTriangle", (req, res) => {<!-- -->
  //Create canvas
  const canvas = createCanvas(400, 400);
  //Get rendering context
  const ctx = canvas.getContext("2d");
  //Draw triangle
  ctx.moveTo(100, 100);
  ctx.lineTo(200, 200);
  ctx.lineTo(50, 100);
  ctx.lineTo(100, 100);
  ctx.stroke();
  //Define the directory and file name to be written
  const imagePath = "./public/images";
  const imageName = "triangle.png";
  //If the images directory does not exist, create one
  if (!fs.existsSync(imagePath)) {<!-- -->
    fs.mkdirSync(imagePath);
  }
  //Write the drawing results to the specified file. Here toBuffer creates a Buffer to represent the image object contained in the canvas. The Buffer object is specially used to process binary data.
  fs.writeFile(`${<!-- -->imagePath}/${<!-- -->imageName}`, canvas.toBuffer(), function (err) {<!-- -->
    if (err) {<!-- -->
      console.log("Writing failed");
    } else {<!-- -->
      console.log("Write successfully");
    }
  });
});

app.listen(port, () => {<!-- -->
  console.log(`Server running at http://${<!-- -->hostname}:${<!-- -->port}/`);
});

When requesting http://localhost:3000/drawTriangle, the triangle will be drawn and written to the public static resource directory:

The browser can then access the image as follows:


Do you think it’s over here? How can drawing be without Echarts? Let’s talk about the rendering of Echarts.

Rendering Echarts chart

Install echarts library

npm install echarts

Introduce echarts library

const echarts = require("echarts");

To render the Echarts chart, the code is as follows:

//server.js
...
const options = {<!-- -->
  title: {<!-- -->
    text: "First ECharts instance",
  },
  tooltip: {<!-- -->},
  legend: {<!-- -->
    data: ["Sales"],
  },
  xAxis: {<!-- -->
    data: ["shirt", "cardigan", "chiffon", "pants", "high heels", "socks"],
  },
  yAxis: {<!-- -->},
  series: [
    {<!-- -->
      name: "Sales",
      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";
  //Initialize echarts and use the created canvas as the initialization container
  const chart = echarts.init(canvas);
  chart.setOption(options);
  //Write to the file, chart.getDom() gets the drawn canvas
  fs.writeFile(`${<!-- -->imagePath}/${<!-- -->imageName}`, chart.getDom().toBuffer(), function (err) {<!-- - ->
    if (err) {<!-- -->
      console.log("Writing failed");
    } else {<!-- -->
      console.log("Write successfully");
    }
  });
});
...

When http://localhost:3000/drawChart is requested, the chart will be rendered:


After rendering is completed, the browser can access:

Conclusion

If this article is helpful to you, you are welcome to follow, like, favorite, comment and support the blogger~