[js高手之路] html5 canvas系列教程 - 像素操作(反色,黑白,亮度,復古,蒙版,透明)

来源:http://www.cnblogs.com/ghostwu/archive/2017/09/28/7606009.html
-Advertisement-
Play Games

接著上文[js高手之路] html5 canvas系列教程 - 狀態詳解(save與restore),相信大家都應該玩過美顏功能,而我們今天要講的就是canvas強大的像素處理能力,通過像素處理,實現反色,黑白,亮度,復古,蒙版,透明等美顏效果. getImageData:獲取一張圖片的像素數據 c ...


接著上文[js高手之路] html5 canvas系列教程 - 狀態詳解(save與restore),相信大家都應該玩過美顏功能,而我們今天要講的就是canvas強大的像素處理能力,通過像素處理,實現反色,黑白,亮度,復古,蒙版,透明等美顏效果.

getImageData:獲取一張圖片的像素數據

cxt.getImageData( x, y, width, height )

x:圖片所在的x坐標

y: 圖片所在的y坐標

width,height 要獲取的像素區域

返回值是一個對象,對象包括一個data屬性, 寬度,高度. data屬性是一個巨大的數組,數組中存儲的是這張圖片的所有像素信息,每四個一組組成一個像素點的信息,如:

[r1,g1,b1,a1, r2,g2,b2,a2...], r( 紅色) g( 綠色) b( 藍色 ) a( 透明度 )

putImageData:輸出像素圖片

putImageData( 像素對象, x, y )

註意:getImageData會產生跨域問題,所以你的程式要放在web伺服器下,我這裡是放在phpstudy下麵.

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset='utf-8' />
 5     <style>
 6         #canvas {
 7             border: 1px dashed #aaa;
 8         }
 9     </style>
10     <script>
11         window.onload = function () {
12             var oCanvas = document.querySelector("#canvas"),
13                 oGc = oCanvas.getContext('2d');
14 
15             var oImg = new Image();
16             oImg.src = './img/mv.jpg';
17             oImg.onload = function () {
18                 oGc.drawImage(oImg, 10, 10);
19                 var imgData = oGc.getImageData(10, 10, 200, 200);
20                 console.log( imgData );
21             }
22         }
23     </script>
24 </head>
25 <body>
26     <canvas id="canvas" width="500" height="400"></canvas>
27 </body>
28 </html>

我這張圖片的尺寸是200 x 200.

一:反色效果

演算法:把每一個像素的r, g, b顏色取反就行,也就是( 255 - 原來的值 )

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset='utf-8' />
 5     <style>
 6         #canvas {
 7             border: 1px dashed #aaa;
 8         }
 9     </style>
10     <script>
11         window.onload = function () {
12             var oCanvas = document.querySelector("#canvas"),
13                 oGc = oCanvas.getContext('2d');
14 
15             var oImg = new Image();
16             oImg.src = './img/mv.jpg';
17             oImg.onload = function () {
18                 oGc.drawImage(oImg, 10, 10);
19                 var imgData = oGc.getImageData(10, 10, 200, 200),
20                     data = imgData.data;
21                 for( var i = 0; i < data.length; i += 4 ) {
22                     data[i] = 255 - data[i];
23                     data[i+1] = 255 - data[i+1];
24                     data[i+2] = 255 - data[i+2];
25                 }
26                 //處理完之後,再次輸出
27                 oGc.putImageData( imgData, 220, 10 );
28             }
29         }
30     </script>
31 </head>
32 <body>
33     <canvas id="canvas" width="500" height="400"></canvas>
34 </body>
35 </html>

二、黑白效果(灰度圖)

 將彩色圖片轉換成黑白圖片,原理:求r(data[i]), g(data[i+1]), b(data[i+2])三個通道的平均值,然後把這個平均值賦值給r, g, b

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset='utf-8' />
 5     <style>
 6         #canvas {
 7             border: 1px dashed #aaa;
 8         }
 9     </style>
10     <script>
11         window.onload = function () {
12             var oCanvas = document.querySelector("#canvas"),
13                 oGc = oCanvas.getContext('2d');
14 
15             var oImg = new Image();
16             oImg.src = './img/mv.jpg';
17             oImg.onload = function () {
18                 oGc.drawImage(oImg, 10, 10);
19                 var imgData = oGc.getImageData(10, 10, 200, 200),
20                     data = imgData.data, avg = 0;
21                 for( var i = 0; i < data.length; i += 4 ) {
22                     avg = ( data[i] + data[i+1] + data[i+2] ) / 3;
23                     data[i] = avg;
24                     data[i+1] = avg;
25                     data[i+2] = avg;
26                 }
27                 //處理完之後,再次輸出
28                 oGc.putImageData( imgData, 220, 10 );
29             }
30         }
31     </script>
32 </head>
33 <body>
34     <canvas id="canvas" width="500" height="400"></canvas>
35 </body>
36 </html>

也可以分配rgb的灰度比例

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset='utf-8' />
 5     <style>
 6         #canvas {
 7             border: 1px dashed #aaa;
 8         }
 9     </style>
10     <script>
11         window.onload = function () {
12             var oCanvas = document.querySelector("#canvas"),
13                 oGc = oCanvas.getContext('2d');
14 
15             var oImg = new Image();
16             oImg.src = './img/mv.jpg';
17             oImg.onload = function () {
18                 oGc.drawImage(oImg, 10, 10);
19                 var imgData = oGc.getImageData(10, 10, 200, 200),
20                     data = imgData.data, avg = 0;
21                 for( var i = 0; i < data.length; i += 4 ) {
22                     avg = data[i] * 0.3 + data[i+1] * 0.3 + data[i+2] * 0.4;
23                     data[i] = avg;
24                     data[i+1] = avg;
25                     data[i+2] = avg;
26                 }
27                 //處理完之後,再次輸出
28                 oGc.putImageData( imgData, 220, 10 );
29             }
30         }
31     </script>
32 </head>
33 <body>
34     <canvas id="canvas" width="500" height="400"></canvas>
35 </body>
36 </html>

三、調節亮度的強弱

在r、g、b、通道上加上一正值就是變亮,加上負值就是變暗

 1 var oImg = new Image();
 2 oImg.src = './img/mv.jpg';
 3 oImg.onload = function () {
 4     oGc.drawImage(oImg, 10, 10);
 5     var imgData = oGc.getImageData(10, 10, 200, 200),
 6         data = imgData.data, avg = 0;
 7     for( var i = 0; i < data.length; i += 4 ) {
 8         data[i] += 30;
 9         data[i+1] += 50;
10         data[i+2] += 50;
11     }
12     //處理完之後,再次輸出
13     oGc.putImageData( imgData, 220, 10 );
14 }

變暗:

data[i] -= 30; data[i+1] -= 50; data[i+2] -= 50;

四、復古效果

 將r, g, b按比例混合相加。

 1 var oImg = new Image();
 2 oImg.src = './img/mv.jpg';
 3 oImg.onload = function () {
 4     oGc.drawImage(oImg, 10, 10);
 5     var imgData = oGc.getImageData(10, 10, 200, 200),
 6         data = imgData.data, avg = 0;
 7     for( var i = 0; i < data.length; i += 4 ) {
 8         r = data[i];
 9         g = data[i+1];
10         b = data[i+2];
11         data[i] = r * 0.3 + g * 0.4 + b * 0.3;
12         data[i+1] = r * 0.2 + g * 0.6 + b * 0.2;
13         data[i+2] = r * 0.4 + g * 0.3 + b * 0.3;
14     }
15     //處理完之後,再次輸出
16     oGc.putImageData( imgData, 220, 10 );
17 }

五、藍色蒙版

藍色 蒙版就是讓圖片偏藍色,將藍色通道賦值為 r, g, b三原色的平均值,把綠色,紅色通道設置為0,其他蒙版效果,只要設置對應的通道平均值,關閉其他通道即可.

 1 var oImg = new Image();
 2 oImg.src = './img/mv.jpg';
 3 oImg.onload = function () {
 4     oGc.drawImage(oImg, 10, 10);
 5     var imgData = oGc.getImageData(10, 10, 200, 200),
 6         data = imgData.data, avg = 0;
 7     for( var i = 0; i < data.length; i += 4 ) {
 8         avg = ( data[i] + data[i+1] + data[i+2] / 3 );
 9         data[i] = 0;
10         data[i+1] = 0;
11         data[i+2] = avg;
12     }
13     //處理完之後,再次輸出
14     oGc.putImageData( imgData, 220, 10 );
15 }

六、透明度

 這個很簡單,只要把透明度乘以一個0~1之間的值即可。跟css的opacity一樣

 1 var oImg = new Image();
 2 oImg.src = './img/mv.jpg';
 3 oImg.onload = function () {
 4     oGc.drawImage(oImg, 10, 10);
 5     var imgData = oGc.getImageData(10, 10, 200, 200),
 6         data = imgData.data, avg = 0;
 7     for( var i = 0; i < data.length; i += 4 ) {
 8         data[i+3] *= 0.2;
 9     }
10     //處理完之後,再次輸出
11     oGc.putImageData( imgData, 220, 10 );
12 }

七、createImageData:根據圖片或者某個寬度與高度創建一個像素區域

cxt.createImageData( w, h )

cxt.createImageData( imgData )

w, h:創建區域的寬度與高度

imgData: 創建的區域與這個像素區域的寬度和高度相同,imgData就是通過getImageData獲取到圖片像素的 返回值

1,根據一個圖片的寬度與高度,創建一個透明的紅色像素區域

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset='utf-8' />
 5     <style>
 6         #canvas {
 7             border: 1px dashed #aaa;
 8         }
 9     </style>
10     <script>
11         window.onload = function () {
12             var oCanvas = document.querySelector("#canvas"),
13                 oGc = oCanvas.getContext('2d');
14 
15             var oImg = new Image();
16             oImg.src = './img/mv.jpg';
17             oImg.onload = function () {
18                 oGc.drawImage(oImg, 10, 10);
19                 var imgData = oGc.getImageData(10, 10, 200, 200),
20                     data = imgData.data,
21                     imgData2 = oGc.createImageData( imgData ),
22                     data2 = imgData2.data;
23                 for( var i = 0; i < imgData2.width * imgData2.height * 4; i += 4 ) {
24                     data2[i] = 255;
25                     data2[i+1] = 0;
26                     data2[i+2] = 0;
27                     data2[i+3] = 30;
28                 }
29                 //處理完之後,再次輸出
30                 oGc.putImageData( imgData2, 220, 10 );
31             }
32         }
33     </script>
34 </head>
35 <body>
36     <canvas id="canvas" width="500" height="400"></canvas>
37 </body>
38 </html>

 

2,自定一個200 x 200的藍色透明像素區域

 1 <!DOCTYPE html>
 2 <html lang="en">
 3 <head>
 4     <meta charset='utf-8' />
 5     <style>
 6         #canvas {
 7             border: 1px dashed #aaa;
 8         }
 9     </style>
10     <script>
11         window.onload = function () {
12             var oCanvas = document.querySelector("#canvas"),
13                 oGc = oCanvas.getContext('2d');
14 
15             var imgData = oGc.createImageData( 200, 200 ),
16                 data = imgData.data;
17                 for( var i = 0; i < imgData.width * imgData.height * 4 ; i += 4 ){
18                     data[i] = 0;
19                     data[i+1] = 0;
20                     data[i+2] = 255;
21                     data[i+3] = 100;
22                 }
23             oGc.putImageData( imgData, 10, 10 );
24         }
25     </script>
26 </head>
27 <body>
28     <canvas id="canvas" width="500" height="400"></canvas>
29 </body>
30 </html>


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 所謂素數是指除了1和它本身以外,不能被任何整數整除的數,例如17就是素數,因為它不能被2~16的任一整數整除。因此判斷一個整數m是否是素數,只需把m被2~m-1之間的每一個整數去除,如果都不能被整除,那麼m就是一個素數另外判斷方法還可以簡化。m不必唄2~m-1之間的每一個整數去除,只需被2~√m之間 ...
  • 修改表 修改表 語法: Alter table <舊表名> rename [ TO] <新表名>; 例子:Alter table `demo01` rename `demo02`; 添加欄位 語法: Alter Table 表名 ADD 欄位名 數據類型 [屬性]; 例子:Alter Table ` ...
  • 第一部分說明 第一部分大概有20來章,主要講的是一些開發常識、開發前中後期準備內容、開發環境與伺服器部署環境安裝設置、python基礎框架結構與功能等內容,代碼會比較簡單。 本系列會以故事的方式,向大家描述一位有點開發基礎的程式猿,怎麼將一個小系統,根據需求的增加,以及對技術的追求,慢慢的通過重構, ...
  • 項目結構 在目錄中運行 ant war 即可. ...
  • 本來應一個可愛帥氣的編輯之邀,要寫一本書《靜兒的互聯網服務治理私房菜》。想選服務治理的題材,想急著簽協議就寫了一個很匆忙的目錄和例章。寫書本是計划了很久的一件事情。現在反而有些猶豫了。我是不是應該把腳步放慢一些,再穩一些。我是不是應該自己先寫了一部分,再考慮簽約出版的事情。要做的事情太多了,比如:家 ...
  • 原文地址: http://michael-j.net/2017/09/24/%E7%BC%96%E7%A8%8B%E5%BF%83%E6%99%BA-%E4%B8%80-%E2%80%94%E2%80%94%E4%BB%A3%E7%A0%81%E6%9E%B6%E6%9E%84%E4%B8%8E%E ...
  • 1.什麼是UML狀態圖 UML狀態圖是描述類對象可能經歷的所有狀態的模型圖,描述了對象基於事件反應的動態行為。顯示實體根據當時的狀態做出具體的動作。 2.UML類圖的作用。 UML類圖的作用是研究類對象,角色,子系統或者其他組件之間的實時行為。 3.UML狀態圖的繪製 3.1 狀態圖的模型組成元素 ...
  • 面向對象編程就是將你的需求抽象成一個對象,針對這個對象分析其特征(屬性)和動作(方法),這個對象稱為“類”。JavaScript 的核心是支持面向對象的,同時它也提供了強大靈活的 OOP 語言能力,遺憾的是對於JavaScript這種解釋性的弱類型語言,沒有強類型語言中那種通過class等關鍵字實現... ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...