JS實(shí)現(xiàn)彩色圖片轉(zhuǎn)換為黑白圖片的3種方法
1. 使用 Canvas
研究 canvas 時(shí)發(fā)現(xiàn)一個(gè)有趣的現(xiàn)象——將彩色圖片巧妙地轉(zhuǎn)換為黑白圖片。以下是實(shí)現(xiàn)這一功能的簡潔代碼示例:
<div style="display: flex"> <img src="./panda.jpeg" /> <button onclick="change()">轉(zhuǎn)換</button> <canvas width="358" height="362"></canvas> </div>
大致步驟為:
1. 把 img 元素畫到 canvas 上
2. 獲取畫布某個(gè)區(qū)域的圖像信息,返回圖片信息對(duì)象
包括 data-類型化數(shù)組(紅,綠,藍(lán),alpha),圖片的寬高等數(shù)據(jù)

3. 重新設(shè)置圖像數(shù)據(jù)到畫布
<script>
function change() {
const img = document.querySelector("img");
const cvs = document.querySelector("canvas");
// 獲取繪圖表面提供 2D 渲染上下文
const ctx = cvs.getContext("2d");
// 把img元素畫到canvas畫布上
ctx.drawImage(img, 0, 0);
// 獲取畫布某個(gè)區(qū)域的圖像信息(整個(gè)圖片區(qū)域)
const imageData = ctx.getImageData(0, 0, img.width, img.height);
// imageData:圖片信息對(duì)象
for (let i = 0; i < imageData.data.length; i += 4) {
// 將灰度值重新賦值給rgba
const r = imageData.data[i];
const g = imageData.data[i + 1];
const b = imageData.data[i + 2];
const avg = (r + g + b) / 3;
imageData.data[i] =
imageData.data[i + 1] =
imageData.data[i + 2] =
avg;
}
// 重新設(shè)置圖像數(shù)據(jù)到畫布
ctx.putImageData(imageData, 0, 0);
}
</script>實(shí)現(xiàn)的效果如下:

注意:需要將 canvas 的 width 和 height 設(shè)置成圖片的真實(shí)大小,否則可能出現(xiàn)轉(zhuǎn)換后圖片尺寸不一致。

黑白圖片的原理
1. 畫布中的一個(gè)圖像是由多個(gè)像素點(diǎn)組成,每個(gè)像素點(diǎn)有四個(gè)數(shù)據(jù):紅、綠、藍(lán)、alpha。

2. 將圖像變成黑白,只需要將圖像的每一個(gè)像素點(diǎn)設(shè)置成當(dāng)前紅、綠、藍(lán)值的平均數(shù)即可。

2. 使用 CSS 濾鏡
如果只是希望在頁面上顯示灰度圖片,而不需要在 JavaScript 中處理圖片數(shù)據(jù),那么可以直接使用 CSS 的 filter 屬性來實(shí)現(xiàn)。代碼如下:
<div>
<img src="./panda.jpeg" />
<button onclick="change()">點(diǎn)擊</button>
</div>
<script>
const change = () => {
const img = document.querySelector('img');
img.style.filter = 'grayscale(100%)'
}
</script>這種方法不會(huì)改變圖片的原始數(shù)據(jù),只是改變了其在頁面上的顯示方式。
效果如下:

3. 使用第三方庫
比如 Three.js 或 Pixi.js,這些庫提供了自己的方法來處理圖像數(shù)據(jù),包括灰度化。如果需要更加精準(zhǔn)的轉(zhuǎn)換操作,可以參考其官方文檔。
到此這篇關(guān)于JS實(shí)現(xiàn)彩色圖片轉(zhuǎn)換為黑白圖片的3種方法的文章就介紹到這了,更多相關(guān)JS 彩色圖片轉(zhuǎn)換黑白圖片內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)運(yùn)動(dòng)步數(shù)排行功能(可刪除)
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)運(yùn)動(dòng)步數(shù)排行功能(可刪除),實(shí)現(xiàn)代碼也很簡單,需要的朋友可以參考下2018-07-07
淺談JavaScript事件綁定的常用方法及其優(yōu)缺點(diǎn)分析
下面小編就為大家?guī)硪黄獪\談JavaScript事件綁定的常用方法及其優(yōu)缺點(diǎn)分析。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-11-11
JavaScript實(shí)現(xiàn)QueryString獲取GET參數(shù)的方法
本文為大家詳細(xì)介紹下如何通過JavaScript實(shí)現(xiàn)QueryString獲取GET參數(shù),具體實(shí)現(xiàn)如下,感興趣的朋友可以參考下哈,希望對(duì)大家有所幫助2013-07-07
分享bootstrap學(xué)習(xí)筆記心得(組件及其屬性)
Bootstrap是一種web框架,是基于HTML,CSS和JS的一種目前較為流行的前端框架。本篇文章將總結(jié)常用組件及其屬性,需要的朋友參考下吧2017-01-01
詳解JS中Array對(duì)象擴(kuò)展與String對(duì)象擴(kuò)展
這篇文章主要介紹了詳解JS中Array對(duì)象擴(kuò)展與String對(duì)象擴(kuò)展的相關(guān)資料,需要的朋友可以參考下2016-01-01
electron 無邊框窗口拖拽移動(dòng)問題及解決辦法
在做一款uTools的插件,懸浮文本,窗口是沒有標(biāo)題欄的,所以需要找一個(gè)地方可以拖動(dòng)移動(dòng)位置,本文給大家介紹electron 無邊框窗口拖拽移動(dòng)問題及解決辦法,感興趣的朋友一起看看吧2023-12-12
Javascript簡單實(shí)現(xiàn)可拖動(dòng)的div
實(shí)現(xiàn)div拖動(dòng)有很多方法,不過目前比較常見的就是使用javascript實(shí)現(xiàn)的了,下面有個(gè)不錯(cuò)的示例,大家可以嘗試操作下2013-10-10
微信小程序?qū)崿F(xiàn)手機(jī)獲取驗(yàn)證碼倒計(jì)時(shí)60s
這篇文章主要為大家詳細(xì)介紹了微信小程序?qū)崿F(xiàn)手機(jī)獲取驗(yàn)證碼后倒計(jì)時(shí)60s,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
詳解JavaScript中原始數(shù)據(jù)類型Symbol的使用
Symbol是es6引入的一個(gè)新的原始數(shù)據(jù)類型,是一個(gè)獨(dú)一無二的值。這篇文章主要為大家介紹了JavaScript中原始數(shù)據(jù)類型Symbol的使用,感興趣的可以了解一下2023-02-02

