canvas學習和濾鏡實現

来源:https://www.cnblogs.com/geyouneihan/archive/2018/08/20/9508167.html
-Advertisement-
Play Games

最近學習了 HTML5 中的重頭戲 。利用 canvas,前端人員可以很輕鬆地、進行圖像處理。其 API 繁多,這次主要學習常用的 API,並且完成以下兩個代碼: 1. 實現去色濾鏡 2. 實現負色(反色)濾鏡 歡迎入群:_857989948_ 。IT 技術深度交流和分享,涉及方麵包括但不限於:網站 ...


最近學習了 HTML5 中的重頭戲--canvas。利用 canvas,前端人員可以很輕鬆地、進行圖像處理。其 API 繁多,這次主要學習常用的 API,並且完成以下兩個代碼:

  1. 實現去色濾鏡
  2. 實現負色(反色)濾鏡

歡迎入群:857989948 。IT 技術深度交流和分享,涉及方麵包括但不限於:網站製作、運營、UI 設計、演算法分析、大數據、人工智慧等。本群主打有深度、有態度的技術交流,歡迎熱衷記錄知識的您的加入。

1 瞭解 canvas?

1.1 什麼是 canvas?

這個 HTML 元素是為了客戶端矢量圖形而設計的。它自己沒有行為,但卻把一個繪圖 API 展現給客戶端 JavaScript 以使腳本能夠把想繪製的東西都繪製到一塊畫布上。

1.2 canvas 和 svg、vml 的區別?

<canvas> 標記和 SVG 以及 VML 之間的一個重要的不同是,<canvas> 有一個基於 JavaScript 的繪圖 API,而 SVG 和 VML 使用一個 XML 文檔來描述繪圖。

2 canvas 繪圖學習

大多數 Canvas 繪圖 API 都沒有定義在 <canvas> 元素本身上,而是定義在通過畫布的getContext()方法獲得的一個“繪圖環境”對象上。而<canvas>元素本身預設的寬高分別是 300px、150px。

2.1 canvas 繪製矩形

// 處理canvas元素
var c = document.querySelector("#my-canvas");
c.width = 150;
c.height = 70;

// 獲取 指定canvas標簽 上的context對象
var ctx = c.getContext("2d");
ctx.fillStyle = "#FF0000"; // 顏色
ctx.fillRect(0, 0, 150, 75); // 形狀

2.2 canvas 繪製路徑

var c = document.querySelector("#my-canvas");
var ctx = c.getContext("2d");
ctx.moveTo(0, 0); // 開始坐標
ctx.lineTo(200, 100); // 結束坐標
ctx.stroke(); // 立即繪製

2.3 canvas 繪製圓形

對於ctx.arc()這個介面,5 個參數是:(x,y,r,start,stop)。其中,x 和 y 是圓心坐標,r 是半徑。

startstop的單位是弧度制。不是長度,也不是 °。

var c = document.querySelector("#my-canvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(95, 50, 40, 0, 2 * Math.PI);
ctx.stroke();

2.4 canvas 繪製文字

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World", 10, 50);

3 canvas 圖像處理學習

3.1 常用 API 介面

關於圖像處理的 API,主要有 4 個:

  • 繪製圖像: drawImage(img,x,y,width,height)drawImage(img,sx,sy,swidth,sheight,x,y,width,height)
  • 獲取圖像數據: getImageData(x,y,width,height)
  • 重寫圖像數據: putImageData(imgData,x,y[,dirtyX,dirtyY,dirtyWidth,dirtyHeight])
  • 導出圖像: toDataURL([type, encoderOptions])

更詳細的 API 和參數說明請看:canvas 圖像處理 API 參數講解

3.2 繪製圖像

在此些 API 的基礎上,我們就可以在canvas元素中繪製我們的圖片。假設我們圖片是./img/photo.jpg

<script>
  window.onload = function () {
    var img = new Image() // 聲明新的Image對象
    img.src = "./img/photo.jpg"
    // 圖片載入後
    img.onload = function () {
      var canvas = document.querySelector("#my-canvas");
      var ctx = canvas.getContext("2d");

      // 根據image大小,指定canvas大小
      canvas.width = img.width
      canvas.height = img.height

      // 繪製圖像
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
    }
  }
</script>

如下圖所示,圖片被畫入了 canvas:
canvas插入圖片

4 實現濾鏡

這裡我們主要借用getImageData函數,他返回每個像素的 RGBA 值。藉助圖像處理公式,操作像素進行相應的、數學運算即可。

什麼是 RGBA?

更多濾鏡實現

4.1 去色效果

去色效果相當於就是老舊相機拍出來的黑白照片。人們根據人眼的敏感程度,給出瞭如下公式:

gray = red * 0.3 + green * 0.59 + blue * 0.11

代碼如下:

<script>
  window.onload = function () {
    var img = new Image()
    img.src = "./img/photo.jpg"
    img.onload = function () {
      var canvas = document.querySelector("#my-canvas");
      var ctx = canvas.getContext("2d");
      canvas.width = img.width
      canvas.height = img.height
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

      // 開始濾鏡處理
      var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      for (var i = 0; i < imgData.data.length / 4; ++i) {
        var red = imgData.data[i * 4],
          green = imgData.data[i * 4 + 1],
          blue = imgData.data[i * 4 + 2];
        var gray = 0.3 * red + 0.59 * green + 0.11 * blue; // 計算gray
        // 刷新RGB,註意:
        // imgData.data[i * 4 + 3]存放的是alpha,不需要改動
        imgData.data[i * 4] = gray;
        imgData.data[i * 4 + 1] = gray;
        imgData.data[i * 4 + 2] = gray;
      }
      ctx.putImageData(imgData, 0, 0); // 重寫圖像數據
    }
  }
</script>

效果如下圖所示:
去色濾鏡

4.2 負色效果

負色效果就是用最大值減去當前值。而 getImageData 獲得的 RGB 中的數值理論最大值是:255。所以,公式如下:

new_val = 255 - val

代碼如下:

<script>
  window.onload = function () {
    var img = new Image()
    img.src = "./img/photo.jpg"
    img.onload = function () {
      var canvas = document.querySelector("#my-canvas");
      var ctx = canvas.getContext("2d");
      canvas.width = img.width
      canvas.height = img.height
      ctx.drawImage(img, 0, 0, canvas.width, canvas.height)

      // 開始濾鏡處理
      var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
      for (var i = 0; i < imgData.data.length / 4; ++i) {
        var red = imgData.data[i * 4],
          green = imgData.data[i * 4 + 1],
          blue = imgData.data[i * 4 + 2];
        // 刷新RGB,註意:
        // imgData.data[i * 4 + 3]存放的是alpha,不需要改動
        imgData.data[i * 4] = 255 - imgData.data[i * 4];
        imgData.data[i * 4 + 1] = 255 - imgData.data[i * 4 + 1];
        imgData.data[i * 4 + 2] = 255 - imgData.data[i * 4 + 2];
      }
      ctx.putImageData(imgData, 0, 0); // 重寫圖像數據
    }
  }
</script>

效果圖如下:
負色濾鏡

本篇文章來自董沅鑫的個人網站,引用、轉載請指明出處

查看更多知識,或者技術交流:請訪問yuanxin.me


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

-Advertisement-
Play Games
更多相關文章
  • "Android項目刮刮獎詳解(一)" 前言 上期我們簡單地實現了一個畫板的功能,用戶可以在上面亂寫亂畫,其實,刮刮獎也是如此,用戶刮獎的時候也是亂寫亂畫的。 刮刮獎原理 一共有兩層畫布,底層畫布存放中獎信息的圖片,上層畫布則是一個遮蓋層,我們將底層畫布成為信息層,上層畫布稱作為遮蓋層。 用戶再遮蓋 ...
  • Element.getBoundingClientRect()返回元素的大小及相對於視窗的位置 語法: rectObject=object.getBoundingClientRect(); 返回值是一個DOMRect對象,即DOMRect={x:scrollLeft,y:scrollY,width: ...
  • css sprites:精靈圖(雪碧圖):把一堆小圖片整合在一張大圖上,通過背景圖片相關設置(背景圖片、背景圖是否重覆、背景圖定位),顯示圖片,減輕伺服器對圖片的請求數量 優點: 1、減少網頁的HTTP請求,提高頁面性能 2、圖片命名上的困擾 3、更換風格方便 缺點: 1、必須限定容器大小,符合背景 ...
  • 一般性的,當我們需要載入js文件的時候都會使用script標簽來實現,類似於如下代碼: 代碼如下: <script type="text/javascript" src="example.js"></script> 但是直接使用script標簽來載入js文件會有如下一些缺點: 1.嚴格的讀取順序。由 ...
  • angularjs學習筆記,系統學習整理angular。angularjs、$scope、$parse、$interpolate ...
  • 這個系列將從基礎語法講起,把react全家桶都講到,然後到具體的使用,最後完成後,會寫一個完整的demo。 前置要求: 基本的CSS,JS要熟練。 部分ES6語法需要瞭解。可以參考下麵提到的阮一峰老師的《ECMAScript 6 入門》和MDN文檔。 目前已經完成的內容: "react教程(零)安裝 ...
  • CSS3實現各種表情 效果圖: 代碼如下,複製即可使用: 如有錯誤,歡迎聯繫我改正,非常感謝!!! ...
  • 最近剛剛看完了《你不知道的 JavaScript》上捲,對 JavaScript 有了更進一步的瞭解。 《你不知道的 JavaScript》上捲由兩部分組成,第一部分是《作用域和閉包》,第二部分是《this 和對象原型》。下麵我會按照簡單介紹一下每一章的主要內容及閱讀感受。 第一部分《作用域和閉包》 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...