基于Node.js實(shí)現(xiàn)一鍵生成個(gè)性化二維碼
在前面
二維碼大家應(yīng)該都用過(guò)了吧,常規(guī)的二維碼都是千篇一律的黑白二維碼,那么我們可不可以讓二維碼變得更有個(gè)性化一點(diǎn)呢?本文將向你展示如何使用Node.js、Jimp和QRCode庫(kù),結(jié)合一個(gè)簡(jiǎn)單的腳本,通過(guò)命令行命令來(lái)快速給二維碼加上指定的背景,打造更有個(gè)性化的二維碼。
效果展示


功能實(shí)現(xiàn)
依賴(lài)引入
const QRCode = require("qrcode");
const fs = require("fs-extra");
const Jimp = require("jimp");
const inquirer = require("@jyeontu/j-inquirer");
const path = require("path");
qrcode:
這是一個(gè)用于生成二維碼的庫(kù)。它支持多種輸出格式,如 Buffer、Canvas、PNG、SVG 等。在這個(gè)腳本中,它被用來(lái)生成二維碼的圖像數(shù)據(jù)。
fs-extra:
fs-extra 是一個(gè)擴(kuò)展了 Node.js 原生 fs 模塊功能的庫(kù),提供了更多實(shí)用的文件系統(tǒng)操作方法,如 copy、move、remove 等。在這個(gè)腳本中,它被用來(lái)寫(xiě)入生成的二維碼圖像到文件系統(tǒng)。
Jimp:
Jimp 是一個(gè)圖像處理庫(kù),它提供了讀取、寫(xiě)入、創(chuàng)建、編輯圖像的功能。在這個(gè)腳本中,它被用來(lái)處理背景圖片和二維碼圖像的合成。
@jyeontu/j-inquirer:
@jyeontu/j-inquirer 是一個(gè)基于 inquirer 的封裝,它提供了一些額外的功能或改進(jìn)。這個(gè)庫(kù)通常用于簡(jiǎn)化命令行界面的創(chuàng)建過(guò)程,使得開(kāi)發(fā)者可以更容易地構(gòu)建交互式的命令行應(yīng)用程序。
path:
path 是 Node.js 的一個(gè)核心模塊,用于處理文件路徑。它提供了解析、連接、標(biāo)準(zhǔn)化路徑等功能。在這個(gè)腳本中,它被用來(lái)構(gòu)建文件路徑,以便正確地保存生成的圖像。
這些模塊共同協(xié)作,使得腳本能夠從用戶(hù)那里獲取必要的信息,生成二維碼圖像,處理背景圖片,并最終將合成后的圖像保存到指定的目錄。
獲取交互參數(shù)
const options = [
{
type: "input",
message: "請(qǐng)輸入二維碼鏈接",
name: "qrCodeUrl",
default: "",
},
{
type: "input",
message: "請(qǐng)輸入二維碼尺寸",
name: "qrCodeSize",
default: "256",
validate: function (input) {
const isNumber = !isNaN(input) && !isNaN(parseFloat(input));
if (isNumber) {
return true; // 輸入有效
} else {
return "請(qǐng)輸入一個(gè)有效的數(shù)字"; // 輸入無(wú)效
}
},
},
{
type: "file",
message: "請(qǐng)選擇背景圖片",
name: "backGroundImg",
default: "",
dirname: baseDir,
},
{
type: "list",
message: "是否保持背景圖片比例",
name: "keepRate",
default: "否",
choices: ["是", "否"],
},
{
type: "folder",
message: "請(qǐng)選擇圖片存放目錄",
name: "outputFolder",
default: "",
dirname: baseDir,
},
];
async function ask(options) {
const answers = await new inquirer(options).prompt();
return answers;
}
const answers = await ask(options);
const { qrCodeUrl, qrCodeSize, backGroundImg, outputFolder, keepRate } = answers;
這段代碼是使用 @jyeontu/j-inquirer 庫(kù)創(chuàng)建的一個(gè)交互式命令行界面。它定義了一個(gè)包含五個(gè)輸入提示的問(wèn)題列表,用于收集用戶(hù)生成二維碼所需的信息。下面是每個(gè)提示的詳細(xì)說(shuō)明:
二維碼鏈接輸入:
- 類(lèi)型:
input - 消息:
請(qǐng)輸入二維碼鏈接 - 名稱(chēng):
qrCodeUrl - 默認(rèn)值:空字符串(
"")
二維碼尺寸輸入:
- 類(lèi)型:
input - 消息:
請(qǐng)輸入二維碼尺寸 - 名稱(chēng):
qrCodeSize - 默認(rèn)值:
256 - 驗(yàn)證:確保輸入是一個(gè)有效的數(shù)字
背景圖片選擇:
- 類(lèi)型:
file - 消息:
請(qǐng)選擇背景圖片 - 名稱(chēng):
backGroundImg - 默認(rèn)值:空字符串(
"") - 目錄:當(dāng)前工作目錄(
baseDir)
保持背景圖片比例:
- 類(lèi)型:
list - 消息:
是否保持背景圖片比例 - 名稱(chēng):
keepRate - 默認(rèn)值:
否 - 選項(xiàng):
["是", "否"]
圖片存放目錄選擇:
- 類(lèi)型:
folder - 消息:
請(qǐng)選擇圖片存放目錄 - 名稱(chēng):
outputFolder - 默認(rèn)值:空字符串(
"") - 目錄:當(dāng)前工作目錄(
baseDir)
ask 函數(shù)使用這個(gè) options 數(shù)組來(lái)創(chuàng)建一個(gè) inquirer 對(duì)話框,并通過(guò) prompt 方法等待用戶(hù)輸入。一旦用戶(hù)完成輸入,answers 對(duì)象將包含所有用戶(hù)的答案。
最后,代碼從 answers 對(duì)象中解構(gòu)出所需的值:qrCodeUrl、qrCodeSize、backGroundImg、outputFolder 和 keepRate。這些值將被用于后續(xù)的二維碼生成和圖片處理邏輯。
生成二維碼圖片
async function generateQRCode(data, size) {
try {
// 設(shè)置二維碼的選項(xiàng)
const options = {
width: size,
height: size,
color: {
dark: "#000000", // 二維碼的深色部分
light: "#ffffff", // 二維碼的淺色部分(透明)
},
};
// 使用 await 等待二維碼生成
const qrCodeBuffer = await QRCode.toBuffer(data, options);
// 將 Base64 字符串轉(zhuǎn)換為 Buffer
const qrCodeBase64 = Buffer.from(qrCodeBuffer).toString("base64");
// 保存二維碼圖片
await fs.writeFile(`qrCode.png`, Buffer.from(qrCodeBuffer));
} catch (error) {
console.error("生成二維碼時(shí)發(fā)生錯(cuò)誤:", error);
}
}函數(shù)參數(shù):
data:要編碼到二維碼中的數(shù)據(jù),通常是一個(gè)字符串,如網(wǎng)址或其他信息。size:二維碼的尺寸,以像素為單位。這個(gè)值將用于設(shè)置二維碼圖像的寬度和高度。
設(shè)置二維碼選項(xiàng):
- 創(chuàng)建一個(gè)選項(xiàng)對(duì)象
options,其中包含二維碼的寬度、高度和顏色設(shè)置。 width和height屬性設(shè)置為傳入的size參數(shù)值,確保二維碼圖像是正方形。color對(duì)象定義了二維碼的深色和淺色。在這里,深色部分(通常是二維碼的條紋)設(shè)置為黑色(#000000),淺色部分(背景)設(shè)置為白色(#ffffff)。
生成二維碼:
- 使用
QRCode.toBuffer方法異步生成二維碼圖像。這個(gè)方法接受data和options作為參數(shù),并返回一個(gè)包含二維碼圖像數(shù)據(jù)的Buffer對(duì)象。 - 將生成的
Buffer對(duì)象保存到名為qrCode.png的文件中。這里使用了fs.writeFile方法,它是fs-extra庫(kù)提供的一個(gè)異步文件寫(xiě)入方法。
錯(cuò)誤處理:
如果在生成二維碼的過(guò)程中發(fā)生錯(cuò)誤,將捕獲這個(gè)錯(cuò)誤并打印到控制臺(tái)。
這個(gè)函數(shù)可以被調(diào)用,傳入需要編碼的數(shù)據(jù)和期望的二維碼尺寸,然后它會(huì)生成一個(gè)二維碼圖像并保存到當(dāng)前工作目錄。
添加背景圖片
async function addBackground(backgroundUrl, size, outputFolder, keepRate) {
try {
// 加載背景圖片并調(diào)整尺寸
const background = await Jimp.read(backgroundUrl);
const width = keepRate === "是" ? background.bitmap.width : size;
const height = keepRate === "是" ? background.bitmap.height : size;
const minLen = Math.min(width, height);
const rate = size / minLen;
await background.resize(width * rate, height * rate); // 調(diào)整背景圖片尺寸
// 加載二維碼圖片
const qrCode = await Jimp.read("qrCode.png");
// 設(shè)置二維碼的透明度,以便可以看到背景圖片
qrCode.opacity(0.5); // 0.5 表示 50% 的透明度
const x = (width * rate - size) / 2,
y = (height * rate - size) / 2;
// 將二維碼放置在背景圖片上
background.composite(qrCode, x, y, {
mode: Jimp.BLEND_SOURCE_OVER,
});
const outPath = path.join(outputFolder, "output.png");
// 保存合成后的圖片
await background.write(outPath);
console.log(`合成后的圖片已保存為 ${outPath}`);
fs.remove("qrCode.png");
} catch (error) {
console.error("添加背景時(shí)發(fā)生錯(cuò)誤:", error);
}
}
將生成的二維碼圖像添加到用戶(hù)選擇的背景圖片上,并保存最終的合成圖像。以下是該函數(shù)的詳細(xì)解釋?zhuān)?/p>
函數(shù)參數(shù):
backgroundUrl:用戶(hù)選擇的背景圖片的路徑。size:二維碼的尺寸,這個(gè)尺寸將用于調(diào)整背景圖片的大小。outputFolder:用戶(hù)指定的輸出目錄,用于保存最終的合成圖片。keepRate:用戶(hù)選擇的是否保持背景圖片比例的選項(xiàng)。
加載背景圖片:
使用 Jimp.read 方法異步加載背景圖片。
調(diào)整背景圖片尺寸:
- 根據(jù)
keepRate的值決定是否保持背景圖片的原始比例。 - 如果
keepRate是 "是",則使用原始圖片的寬度或高度(取較小的一個(gè))作為調(diào)整后的尺寸。 - 如果
keepRate是 "否",則直接使用size參數(shù)作為調(diào)整后的尺寸。 - 計(jì)算調(diào)整后的尺寸與原始尺寸的比例,然后根據(jù)這個(gè)比例調(diào)整背景圖片的尺寸。
加載二維碼圖片:
讀取名為 "qrCode.png" 的二維碼圖片文件。
設(shè)置二維碼透明度:
將二維碼圖片的透明度設(shè)置為 50%,以便在背景圖片上可見(jiàn)。
合成圖片:
- 計(jì)算二維碼在背景圖片上的位置,使其居中顯示。
- 使用
composite方法將二維碼圖片合成到背景圖片上。
保存合成后的圖片:
- 在用戶(hù)指定的輸出目錄中保存合成后的圖片,文件名為 "output.png"。
- 使用
fs.remove方法刪除臨時(shí)生成的 "qrCode.png" 文件。
錯(cuò)誤處理:
如果在處理圖片的過(guò)程中發(fā)生錯(cuò)誤,將捕獲這個(gè)錯(cuò)誤并打印到控制臺(tái)。
這個(gè)函數(shù)是生成個(gè)性化二維碼流程的關(guān)鍵部分,它允許用戶(hù)將二維碼與個(gè)性化的背景圖片結(jié)合,創(chuàng)建一個(gè)獨(dú)特的視覺(jué)作品。通過(guò)調(diào)整透明度和尺寸,用戶(hù)可以在保持背景圖片特征的同時(shí),確保二維碼的可讀性。
插件使用
插件安裝
直接通過(guò)npm進(jìn)行全局安裝。
npm i -g jyeontu
插件使用
安裝完插件之后我們可以執(zhí)行以下命名:
jyeontu img

選擇自定義背景二維碼生成,安裝提示進(jìn)行操作即可。

到此這篇關(guān)于基于Node.js實(shí)現(xiàn)一鍵生成個(gè)性化二維碼的文章就介紹到這了,更多相關(guān)Node.js二維碼內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
輕松創(chuàng)建nodejs服務(wù)器(10):處理POST請(qǐng)求
這篇文章主要介紹了輕松創(chuàng)建nodejs服務(wù)器(10):處理POST請(qǐng)求,本文告訴你如何實(shí)現(xiàn)在node.js中處理POST請(qǐng)求,需要的朋友可以參考下2014-12-12
NodeJs Express框架實(shí)現(xiàn)服務(wù)器接口詳解
最近學(xué)習(xí)了基于前后端分離的開(kāi)發(fā)模式,我前端使用Vue框架,后端使用nodejs開(kāi)發(fā)API接口,下面這篇文章主要給大家介紹了關(guān)于nodejs使用Express框架寫(xiě)后端接口的相關(guān)資料,需要的朋友可以參考下2022-08-08
NodeJS和BootStrap分頁(yè)效果的實(shí)現(xiàn)代碼
這篇文章主要介紹了NodeJS和BootStrap分頁(yè)效果的實(shí)現(xiàn)代碼的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,需要的朋友可以參考下2016-11-11
前端之npm運(yùn)行時(shí)配置文件.npmrc的方法(可用于配置npm淘寶源)
這篇文章主要給大家介紹了關(guān)于前端之npm運(yùn)行時(shí)配置文件.npmrc(可用于配置npm淘寶源)的相關(guān)資料,.npmrc 文件是用于配置 npm(Node.js 包管理器)行為的配置文件,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-07-07
Node.js使用Koa搭建 基礎(chǔ)項(xiàng)目
時(shí)下前端工程師有很多人比較關(guān)注NodeJs以及express 框架或者Koa 框架之類(lèi)的新技術(shù)。難得我最近閑時(shí)較多,利用一下舊歷新年尚未正式到來(lái)的這片閑暇,也來(lái)涉足其中,一窺其中奧妙。2018-01-01

