使用 CamanJS 開(kāi)發(fā)自訂影像編輯器:擴(kuò)展濾鏡選項(xiàng)和混合模式
Aug 28, 2023 am 10:05 AM在我們的 CamanJS 影像編輯器系列的第一個(gè)教學(xué)中,我們僅使用內(nèi)建濾鏡來(lái)編輯影像。這限制了我們一些基本效果,如亮度、對(duì)比度和 18 個(gè)其他更複雜的濾鏡,如 Vintage、Sunrise 等。它們都很容易應(yīng)用,但我們無(wú)法完全控制我們想要的圖像的各個(gè)像素進(jìn)行編輯。
在第二個(gè)教程中,我們了解了圖層和混合模式,這使我們能夠更好地控制正在編輯的圖像。例如,您可以在畫(huà)布上新增一個(gè)新圖層,用顏色或圖像填滿它,然後將其放置在父圖層上並套用混合模式。然而,我們?nèi)匀粵](méi)有創(chuàng)建自己的過(guò)濾器,並且我們可以應(yīng)用的混合模式僅限於 CamanJS 已經(jīng)提供的模式。
本教學(xué)的目的是教您如何創(chuàng)建自己的混合模式和濾鏡。我們還將解決庫(kù)中存在的一些錯(cuò)誤,以及在您自己的專(zhuān)案中使用 CamanJS 時(shí)如何修補(bǔ)它們。
建立新的混合模式
預(yù)設(shè)情況下,CamanJS 提供十種混合模式。它們是正常、相乘、屏蔽、疊加、差值、加法、排除、柔光、變亮和變暗。該庫(kù)還允許您註冊(cè)自己的混合模式。這樣,您就可以控制當(dāng)前圖層和父圖層的相應(yīng)像素如何混合在一起以產(chǎn)生最終結(jié)果。
您可以使用 Caman.Blender.register("blend_mode", callback);
建立新的混合模式。此處,blend_mode
是您要用來(lái)識(shí)別您正在建立的混合模式的名稱?;睾艉瘮?shù)接受兩個(gè)參數(shù),其中包含目前圖層上不同像素和父圖層上對(duì)應(yīng)像素的 RGB 值。該函數(shù)傳回一個(gè)對(duì)象,其中包含 rgb
通道的最終值。
下面是自訂混合模式的範(fàn)例,如果父圖層中對(duì)應(yīng)像素的通道值超過(guò) 128,則該像素的各個(gè)通道的值設(shè)定為 255。如果該值低於 128,則最終通道值是父通道值減去目前層通道值的結(jié)果。此混合模式的名稱是 maxrgb
。
Caman.Blender.register("maxrgb", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r > 128 ? 255 : rgbaParent.r - rgbaLayer.r, g: rgbaParent.g > 128 ? 255 : rgbaParent.g - rgbaLayer.g, b: rgbaParent.b > 128 ? 255: rgbaParent.b - rgbaLayer.b }; });
讓我們以類(lèi)似的方式創(chuàng)建另一個(gè)混合模式。這次,如果父層對(duì)應(yīng)像素的通道值大於128,則最終的通道值將會(huì)被設(shè)定為0。如果父層的通道值小於128,則最終結(jié)果將是相加特定像素的目前圖層和父圖層的通道值。此混合模式已命名為 minrgb
。
Caman.Blender.register("minrgb", function(rgbaLayer, rgbaParent) { return { r: rgbaParent.r < 128 ? rgbaParent.r + rgbaLayer.r : 0, g: rgbaParent.g < 128 ? rgbaParent.g + rgbaLayer.r : 0, b: rgbaParent.b < 128 ? rgbaParent.r + rgbaLayer.r : 0 }; });
您應(yīng)該嘗試建立自己的混合模式進(jìn)行練習(xí)。
建立新的基於像素的濾波器
CamanJS 中有兩大類(lèi)別過(guò)濾器。您可以一次對(duì)整個(gè)影像進(jìn)行一個(gè)像素操作,也可以使用卷積核修改影像。卷積核是一個(gè)矩陣,它根據(jù)某個(gè)像素周?chē)南袼貋?lái)決定該像素的顏色。在本節(jié)中,我們將重點(diǎn)放在基於像素的濾波器。內(nèi)核操作將在下一節(jié)中介紹。
基於像素的濾鏡一次給出一個(gè)像素的 RGB 通道值。該特定像素的最終 RGB 值不受周?chē)袼氐挠绊憽D梢允褂?Caman.Filter.register("filter_name", callback);
建立自己的篩選器。您建立的任何篩選器都必須呼叫 process()
方法。此方法接受過(guò)濾器名稱和回調(diào)函數(shù)作為參數(shù)。
以下程式碼片段向您展示如何建立基於像素的濾鏡,將影像變成灰階。這是透過(guò)計(jì)算每個(gè)像素的發(fā)光,然後將各個(gè)通道的值設(shè)為等於計(jì)算的發(fā)光來(lái)完成的。
Caman.Filter.register("grayscale", function () { this.process("grayscale", function (rgba) { var lumin = (0.2126 * rgba.r) + (0.7152 * rgba.g) + (0.0722 * rgba.b); rgba.r = lumin; rgba.g = lumin; rgba.b = lumin; }); return this; });
您可以以類(lèi)似的方式建立閾值篩選器。這次,我們將允許用戶通過(guò)一個(gè)閾值。如果特定像素的亮度高於使用者提供的限制,則該像素將變成白色。如果特定像素的亮度低於使用者提供的限制,則該像素將變黑。
Caman.Filter.register("threshold", function (limit) { this.process("threshold", function (rgba) { var lumin = (0.2126 * rgba.r) + (0.7152 * rgba.g) + (0.0722 * rgba.b); rgba.r = lumin > limit ? 255 : 0; rgba.g = lumin > limit ? 255 : 0; rgba.b = lumin > limit ? 255 : 0; }); return this; });
作為練習(xí),您應(yīng)該嘗試建立自己的基於像素的過(guò)濾器,例如,增加所有像素上特定通道的值。
CamanJS 還允許您設(shè)定絕對(duì)和相對(duì)位置像素的顏色,而不是操縱目前像素的顏色。不幸的是,這種行為有點(diǎn)錯(cuò)誤,所以我們必須重寫(xiě)一些方法。如果您查看該程式庫(kù)的原始程式碼,您會(huì)注意到getPixel()
和putPixel()
等方法呼叫了 方法<code class="inline">this
上的 和 上的 和。但是,這些方法不是在原型上定義的,而是在類(lèi)別本身上定義的。
這個(gè)函式庫(kù)的另一個(gè)問(wèn)題是 putPixelRelative()
方法在兩個(gè)不同的地方使用變數(shù)名稱 nowLoc
而不是 newLoc
。您可以透過(guò)在腳本中新增以下程式碼來(lái)解決這兩個(gè)問(wèn)題。
Caman.Pixel.prototype.coordinatesToLocation = Caman.Pixel.coordinatesToLocation Caman.Pixel.prototype.locationToCoordinates = Caman.Pixel.locationToCoordinates Caman.Pixel.prototype.putPixelRelative = function (horiz, vert, rgba) { var newLoc; if (this.c == null) { throw "Requires a CamanJS context"; } newLoc = this.loc + (this.c.dimensions.width * 4 * (vert * -1)) + (4 * horiz); if (newLoc > this.c.pixelData.length || newLoc < 0) { return; } this.c.pixelData[newLoc] = rgba.r; this.c.pixelData[newLoc + 1] = rgba.g; this.c.pixelData[newLoc + 2] = rgba.b; this.c.pixelData[newLoc + 3] = rgba.a; return true; };
更正代碼后,您現(xiàn)在應(yīng)該能夠創(chuàng)建依賴于 putPixelRelative()
的過(guò)濾器,沒(méi)有任何問(wèn)題。這是我創(chuàng)建的一個(gè)這樣的過(guò)濾器。
Caman.Filter.register("erased", function (adjust) { this.process("erased", function (rgba) { if(Math.random() < 0.25) { rgba.putPixelRelative(2, 2, { r: 255, g: 255, b: 255, a: 255 }); } }); return this; });
此過(guò)濾器將當(dāng)前像素向上兩行和右側(cè)兩列的像素值隨機(jī)設(shè)置為白色。這會(huì)擦除部分圖像。這就是過(guò)濾器名稱的由來(lái)。
創(chuàng)建新的基于內(nèi)核操作的過(guò)濾器
正如我之前提到的,CamanJS 允許您創(chuàng)建自定義濾鏡,其中當(dāng)前像素的顏色由其周?chē)南袼貨Q定。基本上,這些濾鏡會(huì)遍歷您正在編輯的圖像中的每個(gè)像素。圖像中的一個(gè)像素將被其他八個(gè)像素包圍。圖像中這九個(gè)像素的值乘以卷積矩陣的相應(yīng)條目。然后將所有這些乘積加在一起以獲得像素的最終顏色值。您可以在 GIMP 文檔中更詳細(xì)地了解該過(guò)程。
就像基于像素的過(guò)濾器一樣,您可以使用 Caman.Filter.register("filter_name", callback);
定義自己的內(nèi)核操作過(guò)濾器。唯一的區(qū)別是您現(xiàn)在將在回調(diào)函數(shù)內(nèi)調(diào)用 processKernel()
。
這是使用內(nèi)核操作創(chuàng)建浮雕過(guò)濾器的示例。
Caman.Filter.register("emboss", function () { this.processKernel("emboss", [ -2, -1, 0, -1, 1, 1, 0, 1, 2 ]); });
以下 CodePen 演示將展示我們?cè)诒窘坛讨袆?chuàng)建的所有過(guò)濾器的實(shí)際操作。
最終想法
在本系列中,我?guī)缀鹾w了 CamanJS 在基于畫(huà)布的圖像編輯方面提供的所有內(nèi)容。您現(xiàn)在應(yīng)該能夠使用所有內(nèi)置濾鏡、創(chuàng)建新圖層、在這些圖層上應(yīng)用混合模式以及定義您自己的混合模式和濾鏡功能。
您還可以瀏覽 CamanJS 網(wǎng)站上的指南,以了解我可能錯(cuò)過(guò)的任何內(nèi)容。我還建議您閱讀該庫(kù)的源代碼,以了解有關(guān)圖像處理的更多信息。這也將幫助您發(fā)現(xiàn)庫(kù)中的任何其他錯(cuò)誤。
以上是使用 CamanJS 開(kāi)發(fā)自訂影像編輯器:擴(kuò)展濾鏡選項(xiàng)和混合模式的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

熱AI工具

Undress AI Tool
免費(fèi)脫衣圖片

Undresser.AI Undress
人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門(mén)文章

熱工具

記事本++7.3.1
好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6
視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版
神級(jí)程式碼編輯軟體(SublimeText3)

WordPress導(dǎo)致服務(wù)器CPU使用率飆升的主要原因包括插件問(wèn)題、數(shù)據(jù)庫(kù)查詢效率低、主題代碼質(zhì)量差或流量激增。 1.首先通過(guò)top、htop或控制面板工具確認(rèn)是否為WordPress引起的高負(fù)載;2.進(jìn)入故障排查模式逐步啟用插件排查性能瓶頸,使用QueryMonitor分析插件執(zhí)行情況並刪除或替換低效插件;3.安裝緩存插件、清理冗餘數(shù)據(jù)、分析慢查詢?nèi)照I以優(yōu)化數(shù)據(jù)庫(kù);4.檢查主題是否存在過(guò)度加載內(nèi)容、複雜查詢或缺乏緩存機(jī)制等問(wèn)題,建議用標(biāo)準(zhǔn)主題測(cè)試對(duì)比並優(yōu)化代碼邏輯。按照上述步驟逐一排查可定位並解

MinifyingJavaScript文件可通過(guò)刪除空白、註釋和無(wú)用代碼來(lái)提升WordPress網(wǎng)站加載速度。 1.使用支持合併壓縮的緩存插件如W3TotalCache,在“Minify”選項(xiàng)中啟用並選擇壓縮模式;2.使用專(zhuān)用壓縮插件如FastVelocityMinify,提供更精細(xì)控制;3.手動(dòng)壓縮JS文件並通過(guò)FTP上傳,適用於熟悉開(kāi)發(fā)工具的用戶。注意部分主題或插件腳本可能與壓縮功能衝突,啟用後需徹底測(cè)試網(wǎng)站功能。

優(yōu)化WordPress站點(diǎn)不依賴插件的方法包括:1.使用輕量級(jí)主題,如Astra或GeneratePress,避免功能堆砌的主題;2.手動(dòng)壓縮和合併CSS、JS文件,減少HTTP請(qǐng)求;3.上傳前優(yōu)化圖片,使用WebP格式並控製文件大?。?.配置.htaccess啟用瀏覽器緩存,並接入CDN提升靜態(tài)資源加載速度;5.限製文章修訂版本並定期清理數(shù)據(jù)庫(kù)冗餘數(shù)據(jù)。

TransientsAPI是WordPress中用於臨時(shí)存儲(chǔ)可自動(dòng)過(guò)期數(shù)據(jù)的內(nèi)置工具,其核心函數(shù)為set_transient、get_transient和delete_transient。相比OptionsAPI,transients支持設(shè)置生存時(shí)間(TTL),適合緩存API請(qǐng)求結(jié)果、複雜計(jì)算數(shù)據(jù)等場(chǎng)景。使用時(shí)需注意key命名唯一性與命名空間、緩存“懶刪除”機(jī)制及對(duì)象緩存環(huán)境下可能不持久的問(wèn)題。典型應(yīng)用場(chǎng)景包括減少外部請(qǐng)求頻率、控制代碼執(zhí)行節(jié)奏和提升頁(yè)面加載性能。

防止評(píng)論垃圾信息最有效的方式是通過(guò)程序化手段自動(dòng)識(shí)別並攔截。 1.使用驗(yàn)證碼機(jī)制(如GooglereCAPTCHA或hCaptcha)可有效區(qū)分人類(lèi)與機(jī)器人,尤其適合公眾網(wǎng)站;2.設(shè)置隱藏字段(Honeypot技術(shù)),利用機(jī)器人自動(dòng)填寫(xiě)特性識(shí)別垃圾評(píng)論,不影響用戶體驗(yàn);3.檢查評(píng)論內(nèi)容關(guān)鍵詞黑名單,通過(guò)敏感詞匹配過(guò)濾垃圾信息,需注意避免誤判;4.判斷評(píng)論頻率與來(lái)源IP,限制單位時(shí)間內(nèi)的提交次數(shù)並建立黑名單;5.使用第三方反垃圾服務(wù)(如Akismet、Cloudflare)提升識(shí)別準(zhǔn)確性??筛鶕?jù)網(wǎng)站

在開(kāi)發(fā)Gutenberg塊時(shí),正確enqueue資產(chǎn)的方法包括:1.使用register_block_type指定editor_script、editor_style和style的路徑;2.在functions.php或插件中通過(guò)wp_register_script和wp_register_style註冊(cè)資源,並設(shè)置正確的依賴和版本;3.配置構(gòu)建工具輸出合適的模塊格式,並確保路徑一致;4.通過(guò)add_theme_support或enqueue_block_assets控制前端樣式的加載邏輯,確保

要添加自定義用戶字段需根據(jù)平臺(tái)選擇擴(kuò)展方式並註意數(shù)據(jù)驗(yàn)證與權(quán)限控制。常見(jiàn)做法包括:1.利用數(shù)據(jù)庫(kù)額外表或鍵值對(duì)結(jié)構(gòu)存儲(chǔ)信息;2.在前端加入輸入框並與後端集成;3.對(duì)敏感數(shù)據(jù)進(jìn)行格式校驗(yàn)和訪問(wèn)權(quán)限限制;4.更新接口及模板以支持新字段展示與編輯,同時(shí)兼顧移動(dòng)端適配和用戶體驗(yàn)。

robots.txt對(duì)WordPress網(wǎng)站的SEO至關(guān)重要,能引導(dǎo)搜索引擎抓取行為,避免重複內(nèi)容並提升效率。 1.屏蔽如/wp-admin/、/wp-includes/等系統(tǒng)路徑,但避免誤封/uploads/目錄;2.添加Sitemap路徑如Sitemap:https://yourdomain.com/sitemap.xml以幫助搜索引擎快速發(fā)現(xiàn)站點(diǎn)地圖;3.限制/page/和帶參數(shù)的URL以減少爬蟲(chóng)浪費(fèi),但需注意勿封重要?dú)w檔頁(yè);4.避免常見(jiàn)錯(cuò)誤如誤封全站、緩存插件影響更新及忽略移動(dòng)端與子域名配
