整合营销服务商

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

免费咨询热线:

利用ChatGPT实现SEO自动化:适合初学者的教程

利用ChatGPT实现SEO自动化:适合初学者的教程

不断发展的 SEO 世界中,保持领先地位至关重要。如果你像我一样,你会发现随着搜索算法变得越来越复杂和竞争越来越激烈,SEO资源保持不变甚至减少。因此,我们必须不断寻求创新方法来简化工作流程并提高生产力,才能维持生计。

我们都知道自动化可以帮助我们完成更多工作,而无需增加人员或预算。我相信你们中的许多人都问过自己是否应该深入编码世界以学习如何自动化某些任务。或者,你们中的一些人甚至可能尝试要求一些开发资源来实现这一目标。

如果您仍在阅读,则意味着您在上面认出了自己。这篇文章是写给你的,我的病友!

虽然学习如何编码不一定是解决方案,但仍然有希望的灯塔:进入 ChatGPT。

凭借其处理各种任务的卓越能力,ChatGPT 可以助您一臂之力,在本文中,我们将探讨 ChatGPT 如何彻底改变您实现 SEO 自动化的方式,使您无需具备丰富的编码知识即可取得显着的成果。

但首先,让我们更深入地研究自动化的概念及其在 SEO 领域的意义。

什么是自动化?

自动化是使用技术和工具来简化和简化重复性或耗时任务的过程。它可以让您将宝贵的时间和精力分配给更具战略性的举措,而平凡和重复的活动则由其他系统无缝处理。

有效利用自动化的关键步骤之一是确定要自动化的正确任务。

虽然并非所有任务都适合自动化,但许多流程可以分解为可成功自动化的可管理组件。从长远来看,通过识别这些组件,您可以节省大量时间和精力。

清晰的问题定义对于任何自动化项目都是至关重要的。

它包括理解手头的任务、识别痛点以及定义期望的结果。明确定义的问题陈述为为 ChatGPT 编写有效的提示奠定了基础,并确保自动化流程与预期目标保持一致。

一旦任务被识别并分解,就可以为 ChatGPT 编写提示了。

提示充当提供给模型的指令或查询以生成所需的响应。编写有效的提示需要在足够具体以指导模型和允许模型灵活地生成创造性和准确的响应之间取得平衡。

如何选择自动化项目?

1. 首先列出您每天或每周执行的任务。这些重复性任务的范围从数据分析和报告生成到关键字研究或内容优化以及您能想到的几乎所有其他任务。

2. 将您的列表分为您对如何自动化有大致了解的任务以及那些看起来具有挑战性或不熟悉的任务。前者可能涉及使用现有的工具、脚本或插件,而后者可能需要更多的研究或学习。

3. 优先考虑自动化时能带来最显着效益的任务。考虑诸如您将节省的时间、可能的准确性、可扩展性和潜在的投资回报率等因素。或者简单地考虑一下它是否可以让你保持理智。选择一项与您的目标相符且能够为您的日常工作带来切实改进的任务。

在实践中看到它

我曾经考虑过我可能想要自动化哪些重复性任务,并列出了一个非常简短的列表 - 事实上,从我记事起,我就一直在自动化尽可能多的工作。然而,有一些事情我宁愿不必做,即使它们每个月只发生几次。

从我的列表中,我找到了一个可以节省我一些时间并且还有可能提升我的报告质量的方法:向 Looker Studio 中的图表添加 Google 更新注释。

对于下面的示例,我刚刚使用了以下免费工具和服务:

  • Google 的搜索状态仪表板- 我将使用它作为注释的数据源
  • Google 表格 - 我可以将数据保留在这里,并将其与我的 Analytics 数据混合在 Looker Studio 中
  • ChatGPT - 免费版本就足够了,因为我们不需要任何 Plus 功能。请记住不要分享任何敏感信息,因为您的输入将反馈到学习算法中

作为下一步,我开始思考这可能如何运作。我过去确实有自动化经验,有时可以当场想出一个好的解决方案。

但如果您正在解决一个不容易找到解决方案的问题,请不要担心。在这里,您可以使用 ChatGPT 寻求潜在的解决方案,也可以进行搜索(通过您最喜欢的搜索引擎)以查找其他人针对同一问题提出的解决方案。由于 ChatGPT 有时可能有点太有创意,我更喜欢坚持经典的“只需 Google 即可”。我坚信我永远不是第一个遇到特定问题的人。

以下是我对自动化建议任务的想法:

  • 我可以直接从Google的更新页面获取更新数据。它不仅值得信赖,而且谷歌无论如何都会保持该列表的最新状态,所以我知道这是一个很好的资源。
  • 如果我可以在 Google Sheets 中将该数据以列表形式获取,那么我可以在 Looker studio 中轻松地将其混合,并将其与 GA 或 GSC 数据叠加。
  • 我知道我可以使用 Google 表格中的 IMPORTHTML 函数从网页上抓取信息,因此我需要找出该信息的格式。使用 Chrome 开发人员工具,我可以检查代码并查看是否添加了更新在一个表中。每年都有自己的表格,因此我需要将多个表格导入 Google 表格。

ALT/标题:Google 更新页面和 Chrome 开发者工具呈现的 HTML 代码的屏幕截图,显示该页面是使用表格构建的。

为了验证我的思路,我将快速运行表格中的公式,看看数据是否按需要输入:

ALT/标题:Google 表格中的屏幕截图显示第一个表中的数据

虽然此公式有效,但它仅引入页面上的第一个表(或特定的一个表,但不是全部)。如果我想要的只是今年的更新,那么使用这个公式就足够了。不幸的是,我希望在报告中包含历史数据,因此我需要导入所有表格。

现在我可以将上面的笔记总结为 ChatGPT 的提示:

ALT/标题:ChatGPT 提示的屏幕截图,询问:您好,我想使用 ImportHTML 功能将网页上多个表中的信息获取到 Google 表格中。如果有多个表,我该怎么办?

ALT/标题:ChatGPT 响应的屏幕截图,其中包含有关如何从网页导入表的详细信息。

有趣的是——我们肯定会陷入“我需要帮助”的境地,因为我不熟悉 AppScript。我还注意到,除了代码之外,我还得到了说明和注释——这对我理解它的功能非常方便。

我转到 Google Sheets > 扩展 > AppScript 并在此处创建一个新项目。我将其命名为“Google Updates”,然后将此处的代码替换为 ChatGPT 提供的代码。

在 AppScript 中进行任何更改时以及运行代码之前,请务必点击“保存”。

否则,您可能会因替换但未保存的代码而出现错误,并且必须花时间调试不存在的问题。

看起来 ChatGPT 为我创建了一个特殊的函数,我可以在表格中调用它 - 我按照说明操作,并将该函数与我想要从中获取更新的 URL 结合使用:

=importMultipleTablesFromURL(" https://status.search.google.com/products/rGHU1u87FJnkP6W2GwMi/history ")

但我收到一个错误:

ALT/标题:显示错误的 Google 表格的屏幕截图

我什至没有阅读错误消息,我只是将其复制到 ChatGPT 中:

ALT/标题:描述 Google 表格错误的 ChatGPT 提示的屏幕截图

使用我什至不理解的这条消息,ChatGPT 能够翻译我需要授权才能在表格中覆盖。然后它为我更新代码以包含此内容。

运行新代码后,我确实收到了“审查权限”对话框:

ALT/标题:AppScript 中的“需要授权”对话框的屏幕截图

然后我就可以验证这个脚本并允许它覆盖我的表格。

我再次运行代码,令人惊讶的是,我又收到了另一个错误:

ALT/Caption:AppScript 执行日志错误的屏幕截图

冲洗并重复,我将这个错误反馈给ChatGPT。事实上,我这样做了几次,所有的错误都出现了,并且我不断获得新的代码供我尝试。我只是在这里分享错误和回复的顶行:

ALT/标题:描述错误和响应的 ChatGPT 提示的屏幕截图

ALT/标题:描述错误和响应的 ChatGPT 提示的第二个屏幕截图

ALT/标题:描述错误和响应的 ChatGPT 提示的另一个屏幕截图

我在这里所做的几乎就是调试。我没有自己检查代码并试图找出错误是什么以及如何修复它们,而是将它们反馈给 ChatGPT,它会自行调试。

虽然中间有一些来回,但整个过程不到 5 分钟。我终于得到这个代码:

ALT/标题:ChatGPT 代码片段的屏幕截图

复制粘贴。节省。跑步。我终于成功执行了。切换到我的工作表,这是我看到的:

ALT/标题:显示 3 个表格的 Google Sheets 数据的屏幕截图

到目前为止,一切都很好!所有表格都正在导入,是时候进行一些改进了:

  • 我想将其作为一个列表,只有一个标题而不是多个标题
  • 我想确保新数据覆盖旧数据,这样我就不会意外地得到新旧信息的混杂
  • 我想在 D 列中创建一个名为“更新类型”的新计算字段,并提取主要更新名称
  • 我还想在“E”列中添加一个名为“结束日期”的新字段,该字段使用 B 列“日期”中的数据和 C 列“持续时间”中的数据来计算更新的最后一天

现在我可以将所有这些信息一次性或一次部分反馈给 ChatGPT。我觉得我需要按类型对请求进行分组,所以我首先尝试这样做:

ALT/标题:ChatGPT 提示的屏幕截图,要求仅保留第一个表的标题,并且在更新时不要覆盖数据

从下面的结果可以看出,这个要求不够明确。 ChatGPT 将所有数据放入一列中:

ALT/标题:Google 表格的屏幕截图,在一列中显示所有表格数据

是时候让我的沟通更加清晰,并解释我所看到的以及我想要得到的信息了:

ALT/标题:ChatGPT 提示的屏幕截图更清楚地询问要保留哪些标头

ALT/标题:Google 表格的屏幕截图,显示三个表格,中间有两个空行

肯定越来越近了!我现在只需要删除那些空行。我将再次解释我所看到的以及我想要的结果。

ALT/标题:ChatGPT 提示要求删除空行的屏幕截图

一些改进:

ALT/标题:ChatGPT 提示的屏幕截图,要求再次删除空行,因为仍留下一行

并成功:

ALT/标题:Google 表格的屏幕截图,显示所有三个表格列为一个表格

现在进行下一个改进:

ALT/标题:ChatGPT 提示要求从 A 列中提取更新名称的屏幕截图

结果不是我所期望的,所以我决定举一些例子,涵盖我能看到的所有模式。最后,我们到达了那里:

ALT/标题:Google 表格的屏幕截图,显示表格和带有更新名称的新列

那不是已经很漂亮了吗?让我们看看是否还能获得更新的结束日期,因为该信息不是由 Google 直接提供的。

ALT/标题:ChatGPT 提示要求计算更新长度的屏幕截图

请注意回复中 ChatGPT 如何知道 B 列和 C 列中有哪些值?那只是因为我们之前提到过它们 – ChatGPT 实际上无法看到我们的 Google 表格。

ALT/标题:Google 表格的屏幕截图,显示持续时间为无效持续时间格式

查看具有无效持续时间格式的行,我们可以很快看到只要持续时间不包括小时,它们就会发生。我决定要求 ChatGPT 在计算结束日期之前将持续时间四舍五入到整天 - 这样我们就可以绕过该列中包含不同类型数据的问题。

ALT/标题:Google 表格的屏幕截图显示了预期的持续时间

既然数据看起来不错,那么只剩下一件事情要做了——把这整件事列入时间表。

这可以通过使用触发器从 AppScript 完成,但由于我们使用的是 ChatGPT,我们不妨向它询问最后一个请求:

ALT/标题:ChatGPT 提示要求添加每周触发器的屏幕截图

瞧,这是包含触发器的最终代码:

function importTableAndCalculateUpdateType() {

var url="https://status.search.google.com/products/rGHU1u87FJnkP6W2GwMi/history"; // Replace with the URL of the webpage containing the tables

var response=UrlFetchApp.fetch(url);

var content=response.getContentText();

var tables=content.match(/<table[\s\S]*?<\/table>/g);

var sheet=SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

var lastRow=sheet.getLastRow();

// Clear the sheet except for the first row (header)

if (lastRow > 1) {

sheet.getRange("A2:E" + lastRow).clearContent();

}

var data=[];

tables.forEach(function(table, index) {

var tempData=[];

var tableRows=table.match(/<tr[\s\S]*?<\/tr>/g);

tableRows.forEach(function(rowHTML, rowIndex) {

var rowData=[];

var cells=rowHTML.match(/<t[dh][\s\S]*?<\/t[dh]>/g);

cells.forEach(function(cellHTML) {

var cellText=cellHTML.replace(/<[^>]+>/g, '').trim();

rowData.push(cellText);

});

if (rowData.length > 0 && !(index > 0 && rowIndex===0)) {

tempData.push(rowData);

}

});

if (tempData.length > 0) {

data.push(tempData);

}

});

var startColumn=1; // Starting column to paste data

var startRow=1; // Starting row to paste data

for (var i=0; i < data.length; i++) {

var numRows=data[i].length;

var numCols=data[i][0].length;

sheet.getRange(startRow, startColumn, numRows, numCols).setValues(data[i]);

startRow +=numRows;

}

var updateTypeColumn=4; // Column index for "Update Type" (column D)

var endDateColumn=5; // Column index for "End date" (column E)


// Check and set header for "Update Type" and "End date" if they don't exist

if (sheet.getRange(1, updateTypeColumn).getValue() !=='Update Type') {

sheet.getRange(1, updateTypeColumn).setValue('Update Type');

}

if (sheet.getRange(1, endDateColumn).getValue() !=='End date') {

sheet.getRange(1, endDateColumn).setValue('End date');

}

for (var j=2; j <=sheet.getLastRow(); j++) {

var startDate=sheet.getRange(j, 2).getValue(); // Start date from column B

var duration=sheet.getRange(j, 3).getValue(); // Duration from column C

var endDate=calculatePotentialEndDate(startDate, duration);

sheet.getRange(j, endDateColumn).setValue(endDate);

var text=sheet.getRange(j, 1).getValue();

var updateTypes=extractUpdateTypes(text);

if (updateTypes.length > 0) {

var formattedText=updateTypes.map(word=> formatText(word.replace(/^\d{4}\s/, ''))).join(' ');

sheet.getRange(j, updateTypeColumn).setValue(formattedText);

} else {

sheet.getRange(j, updateTypeColumn).setValue('Other');

}

}

}

function createWeeklyTrigger() {

var day=1; // Monday

var hour=1; // 1 a.m. GMT

var timezone="GMT"; // Set the timezone

ScriptApp.newTrigger("importTableAndCalculateUpdateType")

.timeBased()

.onWeekDay(day)

.atHour(hour)

.inTimezone(timezone)

.create();

}

function extractUpdateTypes(text) {

var matches=text.match(/\d{4}\s([\w\s]+?)\supdate/ig);

return matches ? matches.map(match=> match.replace(/\supdate$/i, '').trim()) : [];

}

function formatText(str) {

return str.toLowerCase().replace(/(?:^|\s)\S/g, function(match) {

return match.toUpperCase();

});

}

function calculatePotentialEndDate(startDate, duration) {

var daysMatch=duration.match(/^(\d+)\s+days?/i);

var hoursMatch=duration.match(/^(\d+)\s+hours?,?\s?[\s\S]*/i);

if (daysMatch) {

var days=parseInt(daysMatch[1]);

var endDate=new Date(startDate);

endDate.setDate(startDate.getDate() + days);

return endDate;

} else if (hoursMatch) {

return new Date(startDate.getTime() + 1 * 24 * 60 * 60 * 1000); // Adding 1 day

} else {

return 'Invalid Duration Format';

}

}

这是最好的方法吗?可能不会。好处是我在 30 分钟内就完成了,只需要一些会话技巧,而且我不必花几个月的时间学习脚本语言。但是,如果我将来确实想学习,ChatGPT 会为我提供可能需要的所有解释。

包起来

如果您来这里只是因为想要成品,请随时创建我的 Google 更新表的副本,您可以将其与 Looker Studio 中的分析数据混合。

以下示例展示了将此数据叠加在流量时间线上后的报告的外观:

ALT/标题:Looker Studio 仪表板的屏幕截图,显示使用 Google 更新注释的网站流量时间线

您还可以对开始日期和结束日期进行三向混合,然后您可以选择任何更新并在图表上查看开始日期和结束日期。您甚至可以给它们不同的颜色。

ALT/标题:Looker Studio 混合面板的屏幕截图,显示三向混合

ALT/标题:Looker Studio 仪表板的屏幕截图,显示流量时间线上的 Coe 更新注释

或者,如果您愿意,您可以创建 Looker Studio 仪表板的副本,将 Google Analytics 数据与 Google Sheets 中的 Google Update 注释结合起来,并查看其设置方式。

如果您有兴趣使用 ChatGPT 自动执行不同类型的 SEO 任务,请继续阅读:

我希望早点做的事情:

  • 告诉 ChatGPT 在代码中使用什么 URL,这样我就不必每次都复制/粘贴它。告诉它我想要公式所在的列和行也是如此。
  • 如果使用 AppScript(以及可能的任何其他集成开发环境),请始终在粘贴后和运行之前保存新代码 - 这将让您不必解决许多不应该存在的错误。
  • 使用示例,但要清楚这些示例用于创建通用模式,而不仅仅是与那些特定值一起使用。
  • ChatGPT 的好坏取决于您的水平 - 如果您不知道自己想要什么,它很可能不会提供给您。

如何改进这个过程:

  • 与开发人员交谈,了解什么是可能的以及什么是可供您使用的。
  • 尝试使用伪代码指令而不是自由言论 - 这可以确保减少解释和错误结果的空间。不知道该怎么做?也许你也可以向 ChatGPT 寻求帮助。
  • 以渐进增强为目标——从小处着手,构建复杂性,不要试图一次完成所有事情。
  • 查看您的数据并注意模式的变化,然后确保提供涵盖所有模式的 ChatGPT 示例。
  • 如果您的代码变得太长(ChatGPT 响应太长),您可以仅关注特定功能,而不是询问完整代码。不管怎样,ChatGPT 都会有这样做的倾向。

最后的想法

如果您决定尝试此过程,请考虑与其他 SEO 分享您的成就。您的成功故事可能会激励人们采用这种方法并增强他们自己的 SEO 工作流程。

此外,在与 ChatGPT 互动时,请记住使用大量的“请”和“谢谢”——你永远不知道人工智能最终统治世界时会记住什么!

天小五与大家分享一个常用的查找引用函数即INDEXC函数,该函数表示在给定的单元格区域中,返回特定行列交叉处单元格的值或引用,那具体怎么使用?通过3个示例一起来看看相应的用法吧。

1、制作小抽奖箱



如何利用Excel制作简单的小抽奖箱?这里与大家分享借用INDEX函数来实现。

在单元格中输入公式=INDEX(A2:A17,RANDBETWEEN(2,COUNTA(A2:A17)))

公式说明:

COUNTA函数表示统计非空单元格格式

RANDBETWEEN函数表示随机生成整数

2、隔行提取数据



在单元格中输入公式=INDEX($A:$A,COLUMN(A1)+(ROW(A1)-1)*2)&""

公式说明:

COLUMN()表示获取相应的列号

ROW()表示获取相应的行号

3、一对多查询

输入公式=IFERROR(INDEX($A:$F,SMALL(IF($C:$C=$I,ROW(:),4^8),ROW(A1)),COLUMN(A1)),""),按Ctrl+Shift+Enter组合键,之后向右向下填充即可。

公式说明:

INDEX表示获取行列交叉数值

语法结构=INDEX(区域,行号,列号)

SMALL函数表示获取第几个最小值

语法结构=SMALL(查找的区域,指定要找第几个最小值)

IF函数表示根据条件进行判断并返回不同的值。

语法结构=IF(条件,条件成立时返回的值,条件不成立时返回的值)

者:前端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    
            }
    }
  },
};

总结

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