整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          HTTP基礎第一篇

          HTTP基礎第一篇

          WEB

          Internet(或Web)是一個龐大的分布式客戶端/服務器信息系統,如下圖所示。

          許多應用程序通過Web同時運行,例如Web瀏覽/沖浪,電子郵件,文件傳輸,音頻和視頻流等。為了在客戶端和服務器之間進行正確的通信,這些應用程序必須就特定的應用程序級協議達成一致,例如HTTP,FTP,SMTP,POP等。

          HTTP

          HTTP(超文本傳輸??協議)可能是Internet(或WEB)中使用的最流行的應用程序協議。HTTP是一種非對稱的請求 - 響應客戶端 - 服務器協議,如圖所示。HTTP客戶端向HTTP服務器發送請求消息。反過來,服務器返回響應消息。換句話說,HTTP是拉協議,客戶端從服務器提取信息(而不是服務器將信息推送到客戶端)。

          • HTTP是無狀態協議。換句話說,當前請求不知道在先前的請求中已經完成了什么。
          • HTTP允許協商數據類型和表示,以便允許獨立于傳輸的數據構建系統。
          • 引自RFC2616:“超文本傳輸協議(HTTP)是一種用于分布式,協作式,超媒體信息系統的應用程序級協議。它是一種通用的無狀態協議,可用于超出其用于超文本的許多任務,例如 作為名稱服務器和分布式對象管理系統,通過擴展其請求方法,錯誤代碼和標題。“

          瀏覽器

          每當您從瀏覽器發出URL以使用HTTP獲取Web資源時,例如 http://www.nowhere123.com/index.html,瀏覽器將URL轉換為請求消息并將其發送到HTTP服務器。 HTTP服務器解釋請求消息,并返回適當的響應消息,該消息是您請求的資源或錯誤消息。 此過程如下所示:

          統一資源定位器(URL)

          URL(統一資源定位符)用于通過Web唯一標識資源。

          URL具有以下語法:

          protocol://hostname:port/path-and-file-name
          

          URL中有4個部分:

          1. 協議:客戶端和服務器使用的應用程序級協議,例如HTTP,FTP和telnet。
          2. 主機名:服務器的DNS域名(例如,www.nowhere123.com)或IP地址(例如,192.128.1.2)。
          3. 端口:服務器正在偵聽來自客戶端的傳入請求的TCP端口號。
          4. 路徑和文件名:服務器文檔基目錄下所請求資源的名稱和位置。

          例如,在URL http://www.nowhere123.com/docs/index.html中,通信協議是HTTP; 主機名是www.nowhere123.com。 URL中未指定端口號,并采用默認號碼,即HTTP的TCP端口80。 要定位的資源的路徑和文件名是“/docs/index.html”。

          URL的其他示例是:

          ftp://www.ftp.org/docs/test.txt
          mailto:user@test101.com
          news:soc.culture.Singapore
          telnet://www.nowhere123.com/
          

          HTTP協議

          如上所述,每當您在瀏覽器的地址欄中輸入URL時,瀏覽器會根據指定的協議將URL轉換為請求消息; 并將請求消息發送到服務器。

          例如,瀏覽器將URL http://www.nowhere123.com/doc/index.html轉換為以下請求消息:

          GET /docs/index.html HTTP/1.1
          Host: www.nowhere123.com
          Accept: image/gif, image/jpeg, */*
          Accept-Language: en-us
          Accept-Encoding: gzip, deflate
          User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
          (blank line)
          

          當此請求消息到達服務器時,服務器可以執行以下任一操作:

          服務器解釋收到的請求,將請求映射到服務器文檔目錄下的文件中,并將請求的文件返回給客戶端。

          請求無法滿足,服務器返回錯誤消息。

          HTTP響應消息的示例如下所示:

          HTTP/1.1 200 OK
          Date: Sun, 18 Oct 2009 08:56:53 GMT
          Server: Apache/2.2.14 (Win32)
          Last-Modified: Sat, 20 Nov 2004 07:16:26 GMT
          ETag: "10000000565a5-2c-3e94b66c2e680"
          Accept-Ranges: bytes
          Content-Length: 44
          Connection: close
          Content-Type: text/html
          X-Pad: avoid browser bug
           
          <html><body><h1>It works!</h1></body></html>
          

          瀏覽器接收響應消息,解釋消息并根據響應的媒體類型在瀏覽器窗口中顯示消息的內容(如Content-Type響應頭中所示)。 常見媒體類型包括“text / plain”,“text / html”,“image / gif”,“image / jpeg”,“audio / mpeg”,“video / mpeg”,“application / msword”和“application /PDF格式”。

          在其空閑狀態下,HTTP服務器除了偵聽配置中為傳入請求指定的IP地址和端口外什么都不做。 當請求到達時,服務器會分析郵件頭,應用配置中指定的規則,并采取相應的操作。 網站管理員對Web服務器操作的主要控制是通過配置,將在后面的部分中詳細介紹。

          HTTP over TCP/IP

          HTTP是客戶端 - 服務器應用程序級協議。 它通常在TCP / IP連接上運行,如圖所示。 (HTTP不僅僅能在TCP / IP上運行。它只假設可靠的傳輸。可以使用任何提供此類保證的傳輸協議。)

          TCP / IP(傳輸控制協議/互聯網協議)是一組傳輸和網絡層協議,用于機器通過網絡相互通信。

          IP(Internet協議)是一種網絡層協議,處理網絡尋址和路由。 在IP網絡中,為每臺機器分配唯一的IP地址(例如,165.1.2.3),并且IP軟件負責將消息從源IP路由到目的地IP。 在IPv4(IP版本4)中,IP地址由4個字節組成,每個字節的范圍為0到255,由點分隔,稱為四點形式。 此編號方案支持網絡上最多4G地址。 最新的IPv6(IP版本6)支持更多地址。 由于記憶號碼對于大多數人來說是困難的,因此使用類似英語的域名,例如www.nowhere123.com。 DNS(域名服務)將域名轉換為IP地址(通過分布式查找表)。 特殊IP地址127.0.0.1始終指您自己的計算機。 它的domian名稱是“localhost”,可用于本地環回測試。

          TCP(傳輸控制協議)是一種傳輸層協議,負責在兩臺機器之間建立連接。 TCP由2個協議組成:TCP和UDP(用戶數據報包)。 TCP是可靠的,每個數據包都有一個序列號,并且需要確認。 如果接收器沒有接收到分組,則將重新發送分組。 TCP保證數據包傳輸。 UDP不保證數據包傳輸,因此不可靠。 但是,UDP具有較少的網絡開銷,可用于視頻和音頻流等應用,其中可靠性并不重要。

          TCP在IP機器中復用應用程序。 對于每臺IP計算機,TCP支持(多路復用)最多65536個端口(或套接字),端口號為0到65535.應用程序(如HTTP或FTP)在特定端口號上運行(或偵聽)傳入請求。 端口0到1023被預先分配給流行協議,例如,80為HTTP,21為FTP,23為Telnet,25為SMTP,NNTP為119,DNS為53.端口1024及以上可供用戶使用。

          盡管TCP端口80已預先分配給HTTP,但作為默認HTTP端口號,這并不禁止您在其他用戶分配的端口號(1024-65535)(如8000,8080)上運行HTTP服務器,尤其是對于測試服務器。 您還可以在同一臺計算機上的不同端口號上運行多個HTTP服務器。 當客戶端在沒有明確說明端口號的情況下發出URL時,例如http://www.nowhere123.com/docs/index.html,瀏覽器將連接到主機www.nowhere123.com的默認端口號80。 您需要在URL中明確指定端口號,例如 http://www.nowhere123.com:8000/docs/index.html如果服務器正在偵聽端口8000而不是默認端口80。

          簡而言之,要通過TCP / IP進行通信,您需要知道(a)IP地址或主機名,(b)端口號。

          HTTP規范

          HTTP規范由W3C(World-Wide Web Consortium)維護,可從http://www.w3.org/standards/techs/http獲得。 目前有兩種版本的HTTP,即HTTP / 1.0和HTTP / 1.1。 由Tim Berners-Lee編寫的原始版本HTTP / 0.9(1991)是一種用于在Internet上傳輸原始數據的簡單協議。 HTTP / 1.0(1996)(在RFC 1945中定義)通過允許類似MIME的消息改進了協議。 HTTP / 1.0不解決代理,緩存,持久連接,虛擬主機和范圍下載的問題。 這些功能在HTTP / 1.1(1999)中提供(在RFC 2616中定義)。

          Apache HTTP Server或Apache Tomcat Server

          研究HTTP協議需要HTTP服務器(例如Apache HTTP Server或Apache Tomcat Server)。

          Apache HTTP服務器是一種流行的工業級生產服務器,由Apache Software Foundation(ASF)@ www.apache.org制作。 ASF是一個開源軟件基金會。 也就是說,Apache HTTP服務器是免費的,帶有源代碼。

          第一個HTTP服務器由Tim Berners Lee在瑞士日內瓦的CERN(歐洲核研究中心)編寫,他也發明了HTML。 Apache于1995年初在NCSA(美國國家超級計算應用中心)“httpd 1.3”服務器上構建.Apache可能因其包含一些原始代碼(來自早期的NCSA httpd Web服務器)和一些原因而得名。補丁; 或者來自美洲印第安部落的名字。

          閱讀關于如何安裝和配置Apache HTTP服務器的“Apache How-to”; 或“Tomcat操作方法”安裝和開始使用Apache Tomcat Server。

          HTTP請求和響應

          HTTP客戶端和服務器通過發送文本消息進行通信 客戶端向服務器發送請求消息。 反過來,服務器返回響應消息。

          HTTP消息由消息頭和可選消息體組成,由空行分隔,如下所示:

          HTTP請求消息

          HTTP請求消息的格式如下:

          請求行

          標頭的第一行稱為請求行,后跟可選的請求標頭。

          請求行具有以下語法

          request-method-name request-URI HTTP-version
          
          • request-method-name:HTTP協議定義一組請求方法,例如GET,POST,HEAD和OPTIONS。客戶端可以使用這些方法之一向服務器發送請求。
          • request-URI:指定請求的資源。
          • HTTP版本:目前正在使用兩個版本:HTTP / 1.0和HTTP / 1.1。

          Request Headers

          請求頭采用name:value對的形式。可以指定以逗號分隔的多個值。

          request-header-name: request-header-value1, request-header-value2, ...
          

          請求頭的示例如下:

          Host: www.xyz.com
          Connection: Keep-Alive
          Accept: image/gif, image/jpeg, */*
          Accept-Language: us-en, fr, cn
          

          Example

          以下顯示了一個示例HTTP請求消息:

          HTTP Response Message

          HTTP響應消息的格式如下:

          Status Line

          第一行稱為狀態行,后跟可選的響應頭。

          狀態行具有以下語法:

          HTTP-version status-code reason-phrase
          
          • HTTP版本:此會話中使用的HTTP版本。 HTTP / 1.0和HTTP / 1.1。
          • status-code:服務器生成的3位數字,用于反映請求的結果。
          • reason-phrase:給出狀態代碼的簡短說明。
          • 常用狀態代碼和原因短語為“200 OK”,“404 Not Found”,“403 Forbidden”,“500 Internal Server Error”。

          狀態行的示例是:

          HTTP/1.1 200 OK
          HTTP/1.0 404 Not Found
          HTTP/1.1 403 Forbidden
          

          Response Headers

          響應標頭的格式為:value對:

          response-header-name: response-header-value1, response-header-value2, ...
          

          響應頭的示例如下:

          Content-Type: text/html
          Content-Length: 35
          Connection: Keep-Alive
          Keep-Alive: timeout=15, max=100
          

          響應消息正文包含所請求的資源數據。

          Example

          以下顯示了示例響應消息:

          第一篇完 喜歡同學可以關注我。

          本文版權歸是三僡然所有,轉載請標明出處。歡迎轉載,歡迎評論,歡迎分享。如果你有文章想分享可以聯系我。

          一年來,伴隨著諸如《使命召喚16》等游戲大作的發售,PC市場又恢復了非常活躍的狀態,特別是今年五一期間,因疫情原因倡導居家不出門,不少小伙伴都提前準備起了“電腦組裝計劃”,打算組裝一臺性能強勁的電腦讓游戲玩的更盡興。不過電腦硬件市場推陳出新速度飛快、價格波動又較大,如何在合適的時間選擇合適的硬件產品,成了不少消費者的選擇難題。

          拼多多發起的“百億補貼”幾乎成為了今天電商行業的標配,5月1日,拼多多開啟了“電腦組裝機,5月購物節”的百億補貼活動,各種爆款硬件產品都有著不錯的優惠價格,不僅是行業底價,還可滿額領券,近期有組裝電腦的小伙伴,不能錯過這次活動了。

          據IT之家了解,本次活動的時間為5月1日-5月12日,在首頁,可領滿198減20、滿298減30、滿398減40、滿498減50、滿980減100、滿1480減150、滿1980減200、滿2480減250 八張券。

          其次,包括顯卡、主板、內存、CPU、硬盤、顯示器等等裝機大件都有著百億補貼優惠價,IT之家這里挑選幾款爆款產品具體來看。

          金士頓SATA3接口A400系列240g固態硬盤,補貼到手價223元,平均1GB不到1元錢,買來裝機又或者是給老筆記本升級,都是不錯的選擇。

          活動地址:點此(點擊鏈接領取優惠券后再購買)

          微星B450M M.2 Max+ AMD R5 3600X套裝,領券后補貼價1619元

          AMD R5 3600X官方定價為1999元,采用7nm Zen2架構,延續AMD良心的AM4接口,內置6核心,支持12線程,基準時鐘頻率3.8GHz,最大加速時鐘頻率4.4GHz,總二級緩存3MB,三級緩存32MB,不鎖頻,基于臺積電TSMC 7nm FinFET工藝,AM4封裝,內置“幽靈” Spire散熱器,默認 TDP 95W。相較于上一代的旗艦R7 2700X,R5 3600X的單核心性能更強,意味著在游戲方面R5 3600X更強,目前3600X是不少玩家們裝機的首選,IT之家這里推薦主板+U的套裝,更具性價比,拼多多百億補貼的微星B450M M.2 Max+ AMD R5 3600X套裝,補貼價1619元,性價比非常高,有需要的值得入手了。

          活動地址:點此(點擊鏈接領取優惠券后再購買)

          影馳RTX2070大將 8G 補貼價2720元

          影馳RTX2070采用了12nm工藝制造的TU104-350 GPU核心,共2304個CUDA單元,RT Cores 達到36個,Tenser Cores達到 288個。采用了與RTX 2080相同的8GB GDDR6顯存,采用了8+6Pin的供電設計,TDP 175W。接口方面包括三枚DP1.4接口、一枚HDMI2.0b接口,一枚Type-C接口。在實際游戲中,諸如《古墓麗影:暗影》這樣的3A大作也能在2K畫質下流暢運行,影馳RTX2070可以說能夠滿足絕大部分的玩家游戲需求。拼多多2720元的補貼價,比市場價平均便宜300元左右,性價比進一步突顯。

          活動地址:點此(點擊鏈接領取優惠券后再購買)

          除了上述產品之外,拼多多還推出了各種豐富的硬件專享價格,IT之家這里就不一一列舉了,小伙伴們可以按需選購。

          電腦組裝機專場:

          https://mobile.yangkeduo.com/promotion_op.html?type=22&id=133691&_x_src=wechat&_x_campaign=platform_itzj0504ft


          百億補貼H5鏈接:

          https://mobile.yangkeduo.com/brand_activity_subsidy.html?_pdd_fs=1&_pdd_tc=ffffff&_pdd_sbs=1&_x_src=wechat&_x_campaign=platform_itzj0504ft

          者:前端Q

          轉發鏈接:https://mp.weixin.qq.com/s/ewFfXptccFs5KvjUINLGbQ

          前端

          小試牛刀,實現了六款簡單常見HTML5 Canvas特效濾鏡,并且封裝成一個純JavaScript可調用的API文件gloomyfishfilter.js。支持的特效濾鏡分別為:

          1.反色

          2.灰色調

          3.模糊

          4.浮雕

          5.雕刻

          6.合理

          濾鏡原理解釋:

          2.灰色調:獲取一個預期點RGB值r,g,b則新的RGB值

          newr=(r * 0.272)+(g * 0.534)+(b * 0.131);

          newg=(r * 0.349)+(g * 0.686)+(b * 0.168);

          newb=(r * 0.393)+(g * 0.769)+(b * 0.189);

          3.模糊:基于一個5 * 5的卷積核

          4.浮雕與雕刻:

          根據當前預期的前一個預期RGB值與它的后一個重新的RGB值之差再加上128

          5.總體:模擬了物體在鏡子中與之對應的效果。

          雜項準備

          1、如何獲取Canvas 2d context對象

          var canvas=document.getElementById("target");
          
          canvas.width=source.clientWidth;
          
          canvas.height=source.clientHeight;
          
          **if**(!canvas.getContext) {
          
             console.log("Canvas not supported. Please install a HTML5compatible browser.");
          
             **return**;
          
          }
          
          // get 2D context of canvas and draw image
          
          tempContext=canvas.getContext("2d");

          2、如何添加一個DOM img對象到Canvas對象中

          var source=document.getElementById("source");
          
          tempContext.drawImage(source, 0, 0, canvas.width,canvas.height);

          3、如何從Canvas對象中獲取預定數據

          var canvas=document.getElementById("target");
          
          var len=canvas.width * canvas.height * 4;
          
          var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
          
          var binaryData=canvasData.data;

          4、如何對DOM對象實現鼠標ClickEvent綁定

          function bindButtonEvent(element, type, handler) 
          {  
          
          if(element.addEventListener){ 
          
                element.addEventListener(type, handler,**false**); 
          
             }else{ 
          
                element.attachEvent('on'+type, handler);// for IE6,7,8
          
             } 
          
          }

          5、如何調用實現的gfilter API完成濾鏡功能

          <scriptsrc=*"gloomyfishfilter.js"*></script> //導入API文件
          
          gfilter.colorInvertProcess(binaryData, len); //調用 API

          6、瀏覽器支持:IE,FF,Chrome上測試通過,其中IE上支持通過以下標簽實現:

          <meta http-equiv="X-UA-Compatible"*content=*"chrome=IE8"> 


          效果演示:

          應用程序源代碼:

          CSS部分:

          #svgContainer {
            width:800px;
            height:600px;
            background-color:#EEEEEE;
          }
          
          #sourceDiv { float: left; border: 2px solid blue} 
          #targetDiv { float: right;border: 2px solid red}

          filter1.html中HTML源代碼:

          <!DOCTYPE html>
          <html>
          <head>
          <meta http-equiv="X-UA-Compatible" content="chrome=IE8">
          <meta http-equiv="Content-type" content="text/html;charset=UTF-8">
          <title>Canvas Filter Demo</title>
          <link href="default.css" rel="stylesheet" />
          <script src="gloomyfishfilter.js"></scrip>
          </head>
          <body>
            <h1>HTML Canvas Image Process - By Gloomy Fish</h1>
            <div id="svgContainer">
              <div id="sourceDiv">
                <img id="source" src="../test.png" />
              </div>
              <div id="targetDiv">
                <canvas id="target"></canvas>
              </div>
            </div>
            <div id="btn-group">
              <button type="button" id="invert-button">反色</button>
              <button type="button" id="adjust-button">灰色調</button>
              <button type="button" id="blur-button">模糊</button>
              <button type="button" id="relief-button">浮雕</button>
              <button type="button" id="diaoke-button">雕刻</button>
              <button type="button" id="mirror-button">鏡像</button>
            </div>
          </body>
          </html>

          filter1.html中JavaScript源代碼:

          var tempContext=null; // global variable 2d context
              window.onload=function() {
                var source=document.getElementById("source");
                var canvas=document.getElementById("target");
                canvas.width=source.clientWidth;
                canvas.height=source.clientHeight;
          
                if (!canvas.getContext) {
                    console.log("Canvas not supported. Please install a HTML5 compatible browser.");
                    return;
                }
          
                // get 2D context of canvas and draw image
                tempContext=canvas.getContext("2d");
                tempContext.drawImage(source, 0, 0, canvas.width, canvas.height);
          
                    // initialization actions
                    var inButton=document.getElementById("invert-button");
                    var adButton=document.getElementById("adjust-button");
                    var blurButton=document.getElementById("blur-button");
                    var reButton=document.getElementById("relief-button");
                    var dkButton=document.getElementById("diaoke-button");
                    var mirrorButton=document.getElementById("mirror-button");
          
                    // bind mouse click event
                    bindButtonEvent(inButton, "click", invertColor);
                    bindButtonEvent(adButton, "click", adjustColor);
                    bindButtonEvent(blurButton, "click", blurImage);
                    bindButtonEvent(reButton, "click", fudiaoImage);
                    bindButtonEvent(dkButton, "click", kediaoImage);
                    bindButtonEvent(mirrorButton, "click", mirrorImage);
              }
          
              function bindButtonEvent(element, type, handler)  
          {  
                if(element.addEventListener) {  
                   element.addEventListener(type, handler, false);  
                } else {  
                   element.attachEvent('on'+type, handler); // for IE6,7,8
                }  
              }  
          
              function invertColor() {
                var canvas=document.getElementById("target");
                var len=canvas.width * canvas.height * 4;
                var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
                var binaryData=canvasData.data;
          
                    // Processing all the pixels
                    gfilter.colorInvertProcess(binaryData, len);
          
                    // Copying back canvas data to canvas
                    tempContext.putImageData(canvasData, 0, 0);
              }
          
              function adjustColor() {
                var canvas=document.getElementById("target");
                var len=canvas.width * canvas.height * 4;
                var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
                    var binaryData=canvasData.data;
          
                    // Processing all the pixels
                    gfilter.colorAdjustProcess(binaryData, len);
          
                    // Copying back canvas data to canvas
                    tempContext.putImageData(canvasData, 0, 0);
              }
          
              function blurImage() 
          {
                var canvas=document.getElementById("target");
                var len=canvas.width * canvas.height * 4;
                var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
          
                    // Processing all the pixels
                    gfilter.blurProcess(tempContext, canvasData);
          
                    // Copying back canvas data to canvas
                    tempContext.putImageData(canvasData, 0, 0);
              }
          
              function fudiaoImage() 
          {
                var canvas=document.getElementById("target");
                var len=canvas.width * canvas.height * 4;
                var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
          
                    // Processing all the pixels
                    gfilter.reliefProcess(tempContext, canvasData);
          
                    // Copying back canvas data to canvas
                    tempContext.putImageData(canvasData, 0, 0);
              }
          
              function kediaoImage() 
          {
                var canvas=document.getElementById("target");
                var len=canvas.width * canvas.height * 4;
                var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
          
                    // Processing all the pixels
                    gfilter.diaokeProcess(tempContext, canvasData);
          
                    // Copying back canvas data to canvas
                    tempContext.putImageData(canvasData, 0, 0);
              }
          
              function mirrorImage() 
          {
                var canvas=document.getElementById("target");
                var len=canvas.width * canvas.height * 4;
                var canvasData=tempContext.getImageData(0, 0, canvas.width, canvas.height);
          
                    // Processing all the pixels
                    gfilter.mirrorProcess(tempContext, canvasData);
          
                    // Copying back canvas data to canvas
                    tempContext.putImageData(canvasData, 0, 0);
              }

          濾鏡源代碼(gloomyfishfilter.js):

          var gfilter={
              type: "canvas",
              name: "filters",
              author: "zhigang",
              getInfo: function () {
                  return this.author + ' ' + this.type + ' ' + this.name;
              },
          
              /**
               * invert color value of pixel, new pixel=RGB(255-r, 255-g, 255 - b)
               * 
               * @param binaryData - canvas's imagedata.data
               * @param l - length of data (width * height of image data)
               */
             colorInvertProcess: function(binaryData, l) {
              for (var i=0; i < l; i +=4) {
                    var r=binaryData[i];
                    var g=binaryData[i + 1];
                    var b=binaryData[i + 2];
          
                    binaryData[i]=255-r;
                    binaryData[i + 1]=255-g;
                    binaryData[i + 2]=255-b;
                }
             },
          
             /**
              * adjust color values and make it more darker and gray...
              * 
              * @param binaryData
              * @param l
              */
            colorAdjustProcess: function(binaryData, l) {
              for (var i=0; i < l; i +=4) {
                    var r=binaryData[i];
                    var g=binaryData[i + 1];
                    var b=binaryData[i + 2];
          
                    binaryData[i]=(r * 0.272) + (g * 0.534) + (b * 0.131);
                    binaryData[i + 1]=(r * 0.349) + (g * 0.686) + (b * 0.168);
                    binaryData[i + 2]=(r * 0.393) + (g * 0.769) + (b * 0.189);
                }
            },
          
            /**
             * deep clone image data of canvas
             * 
             * @param context
             * @param src
             * @returns
             */
            copyImageData: function(context, src)
            {
                var dst=context.createImageData(src.width, src.height);
                dst.data.set(src.data);
                return dst;
            },
          
            /**
             * convolution - keneral size 5*5 - blur effect filter(模糊效果)
             * 
             * @param context
             * @param canvasData
             */
            blurProcess: function(context, canvasData) {
              console.log("Canvas Filter - blur process");
              var tempCanvasData=this.copyImageData(context, canvasData);
              var sumred=0.0, sumgreen=0.0, sumblue=0.0;
              for ( var x=0; x < tempCanvasData.width; x++) {    
                      for ( var y=0; y < tempCanvasData.height; y++) {    
          
                          // Index of the pixel in the array    
                          var idx=(x + y * tempCanvasData.width) * 4;       
                          for(var subCol=-2; subCol<=2; subCol++) {
                            var colOff=subCol + x;
                            if(colOff <0 || colOff >=tempCanvasData.width) {
                              colOff=0;
                            }
                            for(var subRow=-2; subRow<=2; subRow++) {
                              var rowOff=subRow + y;
                              if(rowOff < 0 || rowOff >=tempCanvasData.height) {
                                rowOff=0;
                              }
                              var idx2=(colOff + rowOff * tempCanvasData.width) * 4;    
                                var r=tempCanvasData.data[idx2 + 0];    
                                var g=tempCanvasData.data[idx2 + 1];    
                                var b=tempCanvasData.data[idx2 + 2];
                                sumred +=r;
                                sumgreen +=g;
                                sumblue +=b;
                            }
                          }
          
                          // calculate new RGB value
                          var nr=(sumred / 25.0);
                          var ng=(sumgreen / 25.0);
                          var nb=(sumblue / 25.0);
          
                          // clear previous for next pixel point
                          sumred=0.0;
                          sumgreen=0.0;
                          sumblue=0.0;
          
                          // assign new pixel value    
                          canvasData.data[idx + 0]=nr; // Red channel    
                          canvasData.data[idx + 1]=ng; // Green channel    
                          canvasData.data[idx + 2]=nb; // Blue channel    
                          canvasData.data[idx + 3]=255; // Alpha channel    
                      }
              }
            },
          
            /**
             * after pixel value - before pixel value + 128
             * 浮雕效果
             */
            reliefProcess: function(context, canvasData) {
              console.log("Canvas Filter - relief process");
              var tempCanvasData=this.copyImageData(context, canvasData);
              for ( var x=1; x < tempCanvasData.width-1; x++) 
              {    
                      for ( var y=1; y < tempCanvasData.height-1; y++)
                      {    
          
                          // Index of the pixel in the array    
                          var idx=(x + y * tempCanvasData.width) * 4;       
                  var bidx=((x-1) + y * tempCanvasData.width) * 4;
                  var aidx=((x+1) + y * tempCanvasData.width) * 4;
          
                          // calculate new RGB value
                          var nr=tempCanvasData.data[aidx + 0] - tempCanvasData.data[bidx + 0] + 128;
                          var ng=tempCanvasData.data[aidx + 1] - tempCanvasData.data[bidx + 1] + 128;
                          var nb=tempCanvasData.data[aidx + 2] - tempCanvasData.data[bidx + 2] + 128;
                          nr=(nr < 0) ? 0 : ((nr >255) ? 255 : nr);
                          ng=(ng < 0) ? 0 : ((ng >255) ? 255 : ng);
                          nb=(nb < 0) ? 0 : ((nb >255) ? 255 : nb);
          
                          // assign new pixel value    
                          canvasData.data[idx + 0]=nr; // Red channel    
                          canvasData.data[idx + 1]=ng; // Green channel    
                          canvasData.data[idx + 2]=nb; // Blue channel    
                          canvasData.data[idx + 3]=255; // Alpha channel    
                      }
              }
            },
          
            /**
             *   before pixel value - after pixel value + 128
             *  雕刻效果
             * 
             * @param canvasData
             */
            diaokeProcess: function(context, canvasData) {
              console.log("Canvas Filter - process");
              var tempCanvasData=this.copyImageData(context, canvasData);
              for ( var x=1; x < tempCanvasData.width-1; x++) 
              {    
                      for ( var y=1; y < tempCanvasData.height-1; y++)
                      {    
          
                          // Index of the pixel in the array    
                          var idx=(x + y * tempCanvasData.width) * 4;       
                  var bidx=((x-1) + y * tempCanvasData.width) * 4;
                  var aidx=((x+1) + y * tempCanvasData.width) * 4;
          
                          // calculate new RGB value
                          var nr=tempCanvasData.data[bidx + 0] - tempCanvasData.data[aidx + 0] + 128;
                          var ng=tempCanvasData.data[bidx + 1] - tempCanvasData.data[aidx + 1] + 128;
                          var nb=tempCanvasData.data[bidx + 2] - tempCanvasData.data[aidx + 2] + 128;
                          nr=(nr < 0) ? 0 : ((nr >255) ? 255 : nr);
                          ng=(ng < 0) ? 0 : ((ng >255) ? 255 : ng);
                          nb=(nb < 0) ? 0 : ((nb >255) ? 255 : nb);
          
                          // assign new pixel value    
                          canvasData.data[idx + 0]=nr; // Red channel    
                          canvasData.data[idx + 1]=ng; // Green channel    
                          canvasData.data[idx + 2]=nb; // Blue channel    
                          canvasData.data[idx + 3]=255; // Alpha channel    
                      }
              }
            },
          
            /**
             * mirror reflect
             * 
             * @param context
             * @param canvasData
             */
            mirrorProcess : function(context, canvasData) {
              console.log("Canvas Filter - process");
              var tempCanvasData=this.copyImageData(context, canvasData);
              for ( var x=0; x < tempCanvasData.width; x++) // column
              {    
                      for ( var y=0; y < tempCanvasData.height; y++) // row
                      {    
          
                          // Index of the pixel in the array    
                          var idx=(x + y * tempCanvasData.width) * 4;       
                  var midx=(((tempCanvasData.width -1) - x) + y * tempCanvasData.width) * 4;
          
                          // assign new pixel value    
                          canvasData.data[midx + 0]=tempCanvasData.data[idx + 0]; // Red channel    
                          canvasData.data[midx + 1]=tempCanvasData.data[idx + 1]; ; // Green channel    
                          canvasData.data[midx + 2]=tempCanvasData.data[idx + 2]; ; // Blue channel    
                          canvasData.data[midx + 3]=255; // Alpha channel    
                      }
              }
            },
          };

          總結

          感謝閱讀,如果你覺得我今天分享的內容,不錯,請點一個贊,謝謝!!


          主站蜘蛛池模板: 亚洲熟妇AV一区二区三区浪潮 | 麻豆一区二区在我观看| 在线观看一区二区三区av| 无码AV天堂一区二区三区| av在线亚洲欧洲日产一区二区| 日本免费电影一区| 国产精品亚洲午夜一区二区三区 | 本免费AV无码专区一区| 亚洲国产一区二区视频网站| 天码av无码一区二区三区四区| 精彩视频一区二区| 亚洲国产综合精品一区在线播放| 一区二区三区亚洲视频| 亚洲一区精品伊人久久伊人| 精品亚洲一区二区三区在线观看 | 国产精品99精品一区二区三区| 亚洲av色香蕉一区二区三区| 欧美一区内射最近更新| 国产免费一区二区三区VR| 福利一区国产原创多挂探花| av在线亚洲欧洲日产一区二区| 中文字幕精品亚洲无线码一区| 国产福利精品一区二区| 国产精品视频分类一区| 日本一区二区三区不卡视频| 国产精品一区二区三区久久 | 波多野结衣一区二区免费视频| 影院无码人妻精品一区二区| 中文字幕一区二区三区永久| 精品一区二区久久久久久久网站| 日韩免费无码一区二区三区| 精品久久久久久无码中文字幕一区 | 日本中文字幕一区二区有码在线| 精品一区二区三区东京热| 国产午夜精品一区二区三区极品| 无码人妻精品一区二区三区99不卡| 久久成人国产精品一区二区 | 国产亚洲一区二区精品| 中文字幕人妻AV一区二区| 日韩精品电影一区亚洲| 精品一区二区三区中文字幕|