整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

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    
            }
    }
  },
};

总结

感谢阅读,如果你觉得我今天分享的内容,不错,请点一个赞,谢谢!!