深入了解node-canvas

一、NodeCanvas暫停

NodeCanvas是一個基於node.js的canvas庫,可以使用JavaScript生成圖形,支持多種繪圖操作,像素操作,圖像濾鏡,字體處理,圖像剪裁,圖像合成,PDF輸出等等功能。NodeCanvas提供了一種靈活的方式將canvas應用於伺服器端。

然而,由於NodeCanvas是一個基於C++實現的插件,會存在部分API產生內存泄漏等問題。目前,NodeCanvas已經停止繼續開發了。但是,有些互聯網公司出於自身業務問題,仍在使用NodeCanvas。 而開發者們仍可以自行按照NodeCanvas實現原理,學習學習底層實現的方法。

二、NodeCanvasAPI

NodeCanvas提供了一套基本的API來操作canvas。這些API大部分類 態都是直接使用純JavaScript調用,極其靈活。如果你曾經使用過前端 HTML5中的canvas,那麼使用NodeCanvas去寫伺服器端 繪圖代碼將會變得非常簡單。

以下是一些NodeCanvas常用的API:

// 創建一個新的canvas對象
const { createCanvas } = require('canvas');
const canvas = createCanvas(200, 200);

// 通過繪製矩形來填充一個區域的顏色
const ctx = canvas.getContext('2d');
ctx.fillRect(0, 0, 100, 200);

// 向canvas中渲染text
ctx.font = '30px Impact';
ctx.rotate(0.1);
ctx.fillText('Hello World!', 50, 100);

// 創建一個png編碼的Buffer,將圖像寫入到文件中的方法
const fs = require('fs');
const out = fs.createWriteStream(__dirname + '/text.png');
const stream = canvas.createPNGStream();
stream.pipe(out);
out.on('finish', () => console.log('The PNG file was created.'));

三、NodeCanvas實戰案例

1. 生成二維碼圖片

使用NodeCanvas,可以很容易地生成二維碼圖片。

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

QRCode.toCanvas(canvas, 'https://www.example.com', (error) => {
  if (error) {
    console.error(error)
    return
  }
  console.log('success!');
});

console.log('');

2. 智能圖像識別

使用NodeCanvas可以使用機器學習 AI技術,幫助我們實現智能圖像識別功能。下面通過一個實例代碼來了解這個過程:

// 使用tensorflow.js庫來對圖像進行classification
const sharp = require('sharp');
const tf = require('@tensorflow/tfjs');
const { createCanvas, Image } = require('canvas');

// 將圖像載入到一個ImageData對象中
sharp('image.jpg')
  .resize(224, 224)
  .toBuffer()
  .then(data => {
    const img = new Image();
    img.onload = async () => {
      // 將圖像轉換為Tensor並進行預測
      const tensor = tf.browser.fromPixels(img).expandDims();
      const predictions = await model.predict(tensor).data();

      // 按照順序選擇最大預測概率
      const classes = ['cat', 'dog', 'bird'];
      const res = Array.from(predictions)
                       .map((p, i) => ({ probability: p, className: classes[i] }))
                       .sort((a, b) => b.probability - a.probability)
                       .slice(0, 2);
      console.log(res); // 輸出最大概率的兩個類別
    };
    img.onerror = err => { throw err; };
    img.src = data;
  });

3. 手寫數字識別

// 使用TensorFlow.js進行手寫數字識別
const fs = require('fs');
const { createCanvas, Image } = require('canvas');
const tf = require('@tensorflow/tfjs');

(async () => {
  const model = await tf.loadLayersModel('file://path/to/model.json');
  const canvas = createCanvas(28, 28);
  const input = tf.browser.fromPixels(canvas).reshape([784]);

  // 繪製手寫數字
  const ctx = canvas.getContext('2d');
  ctx.strokeStyle = '#fff';
  ctx.lineWidth = 3;
  ctx.strokeRect(0, 0, 28, 28);
  ctx.lineWidth = 1;

  const _onmousedown = (e) => {
    ctx.beginPath();
    ctx.moveTo(e.offsetX, e.offsetY);
    canvas.addEventListener('mousemove', _onmousemove);
  };

  const _onmousemove = (e) => {
    ctx.lineTo(e.offsetX, e.offsetY);
    ctx.stroke();
  };

  const _onmouseup = (e) => {
    canvas.removeEventListener('mousemove', _onmousemove);

    // 將手寫數字轉換為Tensor並進行預測
    const input = tf.browser.fromPixels(canvas).reshape([784]);
    const output = model.predict(input.expandDims(0));
    const prediction = Array.from(await output.data());
    console.log(prediction.indexOf(Math.max(...prediction))); // 輸出預測結果
  };

  canvas.addEventListener('mousedown', _onmousedown);
  canvas.addEventListener('mouseup', _onmouseup);
})();

總結

NodeCanvas雖然已經停息維護,但是,對於有其他業務需求的開發者來說,使用NodeCanvas仍是一個不錯的選擇。只要我們按照其API進行操作,就可以輕鬆地實現伺服器端的圖像處理,甚至是AI其他相關功能。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/186686.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-27 05:47
下一篇 2024-11-27 05:47

相關推薦

  • 如何解決Node.js中jwt.sign()響應過慢的問題

    本文將從多個方面探討如何解決Node.js中jwt.sign()響應過慢的問題,給出完整的代碼示例與最佳實踐,幫助開發者更好地處理這個問題。 一、問題概述 在使用Node.js編寫…

    編程 2025-04-27
  • n node:全能編程開發工程師

    一、n node——什麼是它? n node是一個多線程的平台,可以用來構建高效的網路應用程序,能夠實現事件驅動、非阻塞I/O的架構。使用n node,開發人員可以用JavaScr…

    編程 2025-04-25
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、位元組與比特 在討論byte轉int之前,我們需要了解位元組和比特的概念。位元組是計算機存儲單位的一種,通常表示8個比特(bit),即1位元組=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟體,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入理解Python字元串r

    一、r字元串的基本概念 r字元串(raw字元串)是指在Python中,以字母r為前綴的字元串。r字元串中的反斜杠(\)不會被轉義,而是被當作普通字元處理,這使得r字元串可以非常方便…

    編程 2025-04-25
  • 深入探討馮諾依曼原理

    一、原理概述 馮諾依曼原理,又稱「存儲程序控制原理」,是指計算機的程序和數據都存儲在同一個存儲器中,並且通過一個統一的匯流排來傳輸數據。這個原理的提出,是計算機科學發展中的重大進展,…

    編程 2025-04-25

發表回復

登錄後才能評論