整合營銷服務商

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

          免費咨詢熱線:

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

          總結

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


          主站蜘蛛池模板: 动漫精品一区二区三区3d | 中文字幕在线观看一区| 精品国产福利一区二区| 日本一区二三区好的精华液| 国产精品亚洲一区二区三区| 中文字幕精品亚洲无线码一区| 亚洲乱码一区二区三区国产精品 | 国产乱码精品一区二区三区中文| 国产乱码精品一区二区三区中 | 国产丝袜无码一区二区视频| 岛国无码av不卡一区二区 | 国产伦精品一区二区三区免.费| 人成精品视频三区二区一区| AA区一区二区三无码精片| 亚洲Aⅴ无码一区二区二三区软件| 五月婷婷一区二区| 国模无码一区二区三区不卡| 国产福利酱国产一区二区| 日韩精品人妻一区二区中文八零| 色窝窝免费一区二区三区| 国产亚洲福利精品一区| 一区二区不卡久久精品| 国产午夜精品一区二区三区极品| 蜜桃臀无码内射一区二区三区| 精品一区二区三区色花堂| 精品日韩一区二区| 日本视频一区在线观看免费| 美女福利视频一区| 海角国精产品一区一区三区糖心| 一区二区在线视频| 久久久精品人妻一区亚美研究所| 国产一区二区三区高清视频| 国产福利电影一区二区三区,日韩伦理电影在线福 | 国产一区二区三区播放心情潘金莲 | 亚洲日韩激情无码一区| 丝袜美腿一区二区三区| 久久久精品人妻一区二区三区蜜桃 | 中文字幕精品无码一区二区三区| 亚洲性日韩精品国产一区二区| 波多野结衣一区二区三区88 | 日本精品一区二区三区在线视频|