如何使用Node.js判斷png圖片是否存在透明像素
背景
png格式的圖片存儲(chǔ)空間會(huì)比jpg格式的圖片大,但是png圖片的質(zhì)量明顯更好。有時(shí)候并不需要圖片的質(zhì)量非常的好,但是為了減少包體,需要做一些優(yōu)化,比如壓縮圖片,把沒(méi)有帶透明像素的png圖片轉(zhuǎn)化成jpg格式的圖片。這片文章主要來(lái)講講怎么利用Node.js來(lái)檢測(cè)沒(méi)有帶透明像素的png圖片,以及如何把它轉(zhuǎn)化成jpg圖片。
代碼
直接上代碼
import canvas from 'canvas';
import fs from 'fs';
/**
* 判斷png圖片是否存在透明像素
*
* @param {*} pngPath png圖片路徑
* @param {number} [limit=255] 透明像素點(diǎn)限度,默認(rèn)小與255視為透明像素
* @param {boolean} [isToJpg=false] 如果沒(méi)有透明像素是否轉(zhuǎn)化為jpg圖片
* @returns
*/
function hasOpacity(pngPath, limit = 255, isToJpg = false) {
// 獲取圖片的buffer
const buffer = fs.readFileSync(pngPath);
// 圖片的寬度存在buffer的第17到20個(gè)字節(jié)
const width = buffer.readUInt32BE(16);
// 圖片的寬度存在buffer的第21到24個(gè)字節(jié)
const height = buffer.readUInt32BE(20);
// 創(chuàng)建一個(gè)畫(huà)布
const pngCanvas = canvas.createCanvas(width, height);
// 拿到畫(huà)筆
const context = pngCanvas.getContext('2d');
// 創(chuàng)建一張圖片
const img = new canvas.Image();
// 記載圖片
img.src = buffer;
// 使用畫(huà)筆把圖片畫(huà)在畫(huà)布上
context.drawImage(img, 0, 0, width, height);
// 獲取png圖片的數(shù)據(jù)的像素?cái)?shù)據(jù)
let res = context.getImageData(0, 0, width, height);
let imgData = res.data;
// 每個(gè)像素占用4個(gè)字節(jié),計(jì)算出一共有多少像素
// [r, g, b, a]
let piexCount = imgData.length / 4;
// 是否已經(jīng)找到透明像素
let isOpacity = false;
for (let i = 0; i < piexCount; i++) {
// 遍歷每個(gè)像素點(diǎn),找透明通道
let opacity = imgData[i * 4 + 3];
if (opacity < limit) {
// 如果小于limit,則存在透明像素,退出
isOpacity = true;
break;
}
}
// 如果不存在透明像素且isToJpg為true,則轉(zhuǎn)化為jpg格式的圖拍呢
if (!isOpacity && isToJpg) {
const out = fs.createWriteStream(pngPath.split('.')[0] + '.jpg');
pngCanvas.createJPEGStream().pipe(out);
out.on('finish', () => console.log(pngPath, '轉(zhuǎn)成jpg成功'));
}
// 返回
return isOpacity;
}
console.log(hasOpacity('hh.png', 254, true));
console.log(hasOpacity('jj.png'));
原理:
canvas采用四個(gè)字節(jié)存放像素,[r, g, b, a],分別代表紅色通道,綠色通道,藍(lán)色通道,透明通道。每個(gè)字節(jié)是8位,所以每個(gè)通道的數(shù)據(jù)是0~255之間,就透明通道而言,255表示完全不透明,0表示完全透明。我們利用Node.js的buffer和canvas把png圖片轉(zhuǎn)化成一個(gè)個(gè)像素點(diǎn)的數(shù)據(jù),然后通過(guò)遍歷每個(gè)透明通道,就可以找到png圖片是否帶有透明像素。
疑問(wèn)?為什么有個(gè)limit參數(shù)?
這是因?yàn)樵趯?shí)際應(yīng)用中,有可能存在少量254、253的透明通過(guò),這些看起來(lái)就跟完全不透明的像素一樣,所以把他們也當(dāng)作不是透明像素處理。這個(gè)根據(jù)自己能夠接受的限度去傳參。
實(shí)例圖片
帶透明像素

不帶透明像素

canvas
關(guān)于canvas的更多使用,請(qǐng)參考 www.npmjs.com/package/can…
總結(jié)
到此這篇關(guān)于如何使用Node.js判斷png圖片是否存在透明像素的文章就介紹到這了,更多相關(guān)Node.js判斷png圖片透明像素內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
node.js [superAgent] 請(qǐng)求使用示例
這篇文章主要介紹了node.js [superAgent] 請(qǐng)求使用示例,分別給大家匯總了post請(qǐng)求、get請(qǐng)求、delete請(qǐng)求和put請(qǐng)求的示例,推薦給大家,希望大家能夠喜歡。2015-03-03
修改Nodejs內(nèi)置的npm默認(rèn)配置路徑方法
今天小編就為大家分享一篇修改Nodejs內(nèi)置的npm默認(rèn)配置路徑方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-05-05
NodeJS創(chuàng)建基礎(chǔ)應(yīng)用并應(yīng)用模板引擎
這篇文章主要介紹了NodeJS創(chuàng)建基礎(chǔ)應(yīng)用并應(yīng)用模板引擎的相關(guān)資料,需要的朋友可以參考下2016-04-04
Node.js中使用計(jì)時(shí)器定時(shí)執(zhí)行函數(shù)詳解
這篇文章主要介紹了Node.js中使用計(jì)時(shí)器定時(shí)執(zhí)行函數(shù)詳解,本文使用了Node.js中的setTimeout和setInterval函數(shù),需要的朋友可以參考下2014-08-08
Node.js實(shí)現(xiàn)簡(jiǎn)單管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Node.js實(shí)現(xiàn)簡(jiǎn)單管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-09-09
node.js如何自定義實(shí)現(xiàn)一個(gè)EventEmitter
我們了解到,Node采用了事件驅(qū)動(dòng)機(jī)制,而EventEmitter就是Node實(shí)現(xiàn)事件驅(qū)動(dòng)的基礎(chǔ),本文主要介紹了node.js自定義實(shí)現(xiàn)EventEmitter,感興趣的可以了解一下2021-07-07

