在上一篇文章裡,我們解釋了為濾鏡添加術語資源,從而使我們的濾鏡可以被PS的scripting system感知和描述,這樣即友好支持了PS的「動作」面板。在這篇文章中,我們將對先前的DEMO進行進一步的細化,例如在參數對話框上增加即時預覽的小縮圖等。對話框的引入主要是給使用者一個機會和接口,設定或調節濾鏡所使用的影像處理演算法。通常作為UI的友善性,在對話方塊上應該提供預覽圖,這樣可以直覺的把參數對結果產生的影響回饋給用戶,指導他們調整參數。而不是要使用者必須重複執行濾鏡指令才能看到效果然後去調節參數。
之前我覺得「加入縮圖」這樣的功能應該不是很困難,但當我嘗試這樣去做,我很快發現它的難度遠遠超過了以往我寫的文章中的講解。因為當我們嘗試使用PS提供的回調函數去顯示縮圖時,我們必須對PS提供的介面細節完全清楚,包括影響縮放的參數設置,資料分佈,掃描行等細節。不能夠有一分一毫的差錯,否則我們就可能看到不正常的顯示,甚至會不小心的使記憶越界。
在引入縮圖之前,且我先對濾鏡演算法做一些有趣的改進,並進行了一點增強,使它更加實用化。
(1)導入「像素隨機抖動」參數與演算法。
在先前設定像素時,輸入與輸出的位置原本是完全一致的,即Dest(i, j) = f (Src(i, j))。
現在我們考慮對上式進行一點改變,將來源像素進行隨機抖動,即Dest(i, j) = f (Src(i+dx, j+dy))。
我們設定抖動距離為distance(像素)參數,這樣我們取源像素時,以目前像素為中心向外圍擴展distance的正方形內隨機選取某點作為源像素。從而使他們在結果圖中具有一種“溶解”或“腐蝕”效果。如下圖所示:
因此我們在中音距參數中增加了distance參數,並表示上方圖中的隨機抖動距離參數。這樣當我們設定位於(i,j)位置的像素時,我們取的來源像素座標是:
x = i + rand()%(2*distance+1) - distance;
y = j + rand()%(2*distance+1) - distance;
## 把x,y限定在filterRect 內部。
而因我們所使用的是使用貼片(Tile)處理方式,因此我們的調整需要一點技巧性。我們將改變我們向PS請求的inRect,即每次貼片時,outRect依然保持和此前一致,而把inRect 嘗試向四周擴張distance像素距離,這樣可以保證我們每次貼片時都能拿到有效數據(當貼片位於filterRect內部時),除非貼片位於filterRect的邊緣。
必須注意的是,由於inRect 比outRect 要“大一圈”,所以這時候兩個Rect的像素已經不是大小一致完全重疊關係了,而是有一定重疊關係了,而是有一定重疊關係移
的!在程式碼中我們必須考慮兩個矩形之間的偏移關係。這裡可以參考我的原始碼,就不詳細講解該處理方法了。
(2)為對話方塊增加「縮圖」(Proxy)。
#######我們增加了一個參數,然後在對話方塊左側空出一個較小區域用於顯示縮圖,為了方便,我在縮圖位置放置了一個隱藏的STATIC 控制項(Proxy Banner),它的主要用處是使我可以在運行時獲取到“縮圖”的邊界(客戶區坐標)。修改後的對話方塊如下圖:
為
‧
typedef MACPASCAL OSErr (*DisplayPixelsProc) ( const VRect *srcRect, int32 dstCol,
void * platformContext);
typedef struct PSPixelMap { int32 version; VRect bounds; int32 imageMode; int32 rowBytes; int32 colBytes; int32 planeBytes; void *baseAddr; //--------------------------------------------------------------------------- // Fields new in version 1: //--------------------------------------------------------------------------- PSPixelMask *mat; PSPixelMask *masks; // Use to set the phase of the checkerboard: int32 maskPhaseRow; int32 maskPhaseCol; //--------------------------------------------------------------------------- // Fields new in version 2: //--------------------------------------------------------------------------- PSPixelOverlay *pixelOverlays; unsigned32 colorManagementOptions; } PSPixelMap;
#
◆ version: 結構體版本。 對於PS CS版本來說,它要求我們將它設為1。 PS的未來版本可能會擴展它並提升此版本號。
◆ ):像素資料所佔據的長方形。◆ imageMode:資料區的影像模式。
它支援下列模式: grayscale, RGB, CMYK, Lab。
◆ rowBytes: 相鄰行間的位元組數距離。相當於掃描程式寬度(重要),以位元組為單位,且必須設定正確。
◆ colBytes: 鄰近列像素資料的位元組數距離。由於資料是「集中分佈」的,所以這個屬性的值主要取決於像素的色深度。對於每個通道每個像素使用一個位元組的普通24位元深度的圖像來說,這個距離為1byte。
◆ planeBytes: 鄰近通道的位元組數距離。
由於資料是「集中分佈」的,因此這個特性通常是 rowBytes * 影像高度。
◆ baseAddr:資料區起始位址。
我曾在先前的文章中曾被檢視,PS提供給我們的 inData 和 outData 是通道交叉分佈的(interleave)。而這裡PSPixelMap中的資料的分佈需求則不同,它要求資料是通道集中分佈的。
例如對RGB影像來說, 當我們要求所有頻道時,inData/outData中的資料分佈為:
G | B | ..... (interleave)
而而對PSPixelMap 中的資料來說,則要求依下列分佈:
G | G | ... B | B | B .... (集中分佈)
也就是說對inData 與outData,所有頻道資料交叉分佈,同一個頻道(plane)的資料在資料區中是跳躍式存在的。
而對 PSPixelMap 來說,同一個通道(plane)的資料是集中在一起的,先列出所有第一個通道數據,再列出所有第二個通道數據,等等。
同時我們進行像素定位與預測緩衝區大小時,與普通的Bitmap像素定位一樣,必須使用濾鏡參數中的inRowBytes 屬性(相當於掃描行寬度)進行在「行」間定位,而不能假設或自行計算“行寬度”。
【注意】我們必須清楚資料分佈的細節,這樣才能正確定位到指定位置的像素。
(2.2)控制縮放:FilterRecord中的inputRate 與inputPadding 屬性;#
1# 因此我們顯示縮圖時必然面對的一個問題是縮放問題。大多數情況下,由於縮圖只是定性展示,對資料精確性要求可以有所降低,並且考慮到性能因素,因此一般縮圖的尺寸可以設定的較小,當原圖(filterRect)比縮圖( bannerRect)大時,我們希望影像縮小顯示在縮圖上。而當原圖比縮圖小時,我們就採用實際原圖大小(即縮放因子=1)即可。因此現在我們需要了解如何把原圖縮小到縮圖大小。在GDI中我們知道我們可以使用StretchBlt 函數來完成縮放的。而在這裡我們取得來源圖資料是從PS傳遞給我們的inData得到的,當我們希望得到縮小的原圖時,我們也就是透過設定 FilterRecord 參數中的 inputRate (取樣率)屬性來完成縮小。
(2.2.1)Fixed inputRate;
==== ================================= 【關於Fixed 類型】 在PS中定義為long 類型: typedef long Fixed; 所謂Fixed是相對 float(浮點小數)來說的。在float中小數點的位置是不固定的,因此稱為浮動點。而 Fixed 則把一個小數拆解為整數部分和小數部分,分別儲存到一個高16位元和低16位元。即其意義是 "16.16"。 例如假設一個小數是3.00f;則對應的Fixed數是 0x00030000; 㠀#double _factor;
## #Fixed _fixed = ( Fixed ) ( _factor * 0x10000 ) ; #
##
從Fixed 類型轉換成浮點型別的方法是( 備註:1 / 0x10000 = 0.0000152587890625 ) :
# Fixed _fixed;
#double
#
#fa_f##1_faf## nx *
0.0000152587890625;
======================= ===========================
inRect.right * inputRate, inRect.bot .0 時,則每兩個像素採樣一個點,則inRect, inData 的關係如下圖所示:
在此中針對需要把我們希望的inRect(粉紅矩形區域)的座標除以inputRate(圖中假設inputRate = 2),才是需要提交給PS的inRect(上圖的藍色矩形)。然後我們使用advanceProc回呼函數,即可得到 inData 為上圖中右側的影像數據,可見它的尺寸在兩個方向上都縮小了一半。 【注意1】處理完畢縮圖並關閉對話方塊時,必須將inputRate恢復為 0x00010000 (1.0)。否則它將繼續影響後續的實際處理中的 inData!使處理結果產生意料外的結果。 ###### 【注意2】濾鏡參數必須考慮影像縮放所帶來的影響。和縮放有關的參數也要對應的映射到縮圖尺寸上(例如本例中的隨機抖動距離要同比例縮小)。和縮放無關的參數(例如本例中的不透明度百分比,填充色)可不考慮縮放影響。 ###### ###### ###(2.2.2)int16 inputPadding;######### 可以指定補齊的像素的值(0~255),也可以設定為以下選項(它們被定義為負數,以和使用者設定像素值區別):###### ###plugInWantsEdgeReplication: 复制边缘像素。
plugInDoesNotWantPadding:随机值(不确定的值)。
plugInWantsErrorOnBoundsException:(默认值)请求边界外数据时标记一个错误。
当请求区域超出边界,PS将使用上述选项设置 inData 的数据。
(2.2.3)显示缩略图。
为了显示缩略图,我们需要请求PS为我们分配缓冲区。我们首先需要预测我们的缓冲区的大小,并在Prepare调用时通知 PS 我们的需求。
考虑到当用户在对话框上进行参数调整时,我们应该实时的更新缩略图显示,以反馈当前参数效果。所以我们需要两份缩略图数据,一份是缩略图的原始数据,它作为算法的输入,在创建对话框时获取到源图数据,然后在整个对话框生命期间保持数据不会改变。另一份是我们用于处理 WM_PAINT 消息时使用的绘制数据,即可以实时改变的缩略图实际显示数据。
因此我们评估缩略图的尺寸,然后使用以下估计值:
bufferSize = 缩略图最大宽度 * 缩略图最大高度 * 通道数 * 2;
在 Prepare 调用期间,我们把这个值(bufferSize)设置到 FilterRecord 的 bufferSpace 和 maxSpace 属性中,这表示我们(PlugIn)和PS(Host)进行内存需求“协商”,使 PS 了解到我们预期的内存开销,然后尝试准备足够内存以供我们后续的申请。
真正显示对话框是在 start 调用中,我们在对话框的初始化消息时准备请PS为我们申请缓冲区。基本方式如下:
//获取 buffer 回调函数集指针 BufferProcs *bufferProcs = gFilterRecord->bufferProcs; //请PS为我们申请内存 bufferProcs->allocateProc(bufferSize, &m_ProxyData.bufferId0); //请PS为我们锁定内存(禁止内存整理) //[ 1 ]函数返回被锁定的内存起始地址。 //[ 2 ]第二个参数是BOOL moveHigth,对windows平台将被忽略。 m_ProxyData.data0 = bufferProcs->lockProc(m_ProxyData.bufferId0, TRUE); //============================= // 这里是处理和更新缓冲区的期间 //============================= //使用结束后,释放和解锁缓冲区。 //解锁 gFilterRecord->bufferProcs->unlockProc(m_ProxyData.bufferId0); //释放内存 gFilterRecord->bufferProcs->freeProc(m_ProxyData.bufferId0);
我们使用 lockProc 锁定缓冲区这块内存,主要是防止操作系统在我们处理数据期间进行内存整理,从而破坏缓冲区资源。
【注意】这里加锁和解锁使用的是“引用计数”机制,即解锁次数 必须 匹配加锁次数才能使缓冲区真正得到解锁。
为了显示缩略图,并能够实时反馈用户的调节,我们准备了下面的四个函数(其中CreateProxyBuffer 和 UpdateProxy 难度最大):
● CreateProxyBuffer
计算缩略图实际大小和缩放因子,委托PS为我们申请缓冲区,同时也初始化了原始数据(即把inData拷贝到PsPixelMap中),在处理 WM_INITDIALOG 时调用。
● UpdateProxy
当用户在对话框上修改了某个参数时(WM_COMMAND)被调用,用于更新缩略图显示数据,并刷新缩略图显示。会引起对 PaintProxy 函数的间接调用。
● PaintProxy
绘制缩略图,通过 displayPixels 回调函数完成,在处理 WM_PAINT 消息时调用。
● DeleteProxyBuffer
释放我们申请的缓冲区,在对话框退出前(WM_DESTROY)调用。
现在总结一下上面四个函数的调用时机,使我们对这四个函数的分工具有一个明确的认识,如下表:
#視窗訊息 |
##事件 |
#被呼叫的函數 |
|
#說明 |
WM_INITDIALOG |
建立對話框 |
|
#WM_COMMAND |
|||
##########修改參數值###################UpdateProxy##############################UpdateProxy################# #更新縮圖,將間接呼叫###PainProxy#####################WM_PAINT######################################################################################### ##視窗繪製###### |
PaintProxy |
#繪製縮圖 |
|
##WM_DESTROY |
#退出對話方塊 |
##DeleteProxyBuffer
|
釋放縮圖緩衝區
|

Photoshop不是免費的,但有幾種方式可以低成本或免費使用:1.免費試用期為7天,期間可體驗所有功能;2.學生和教師優惠可將成本減半,需提供學校證明;3.CreativeCloud套餐適合專業用戶,包含多種Adobe工具;4.PhotoshopElements和Lightroom為低成本替代方案,功能較少但價格更低。

Photoshop值得投資,因為它提供了強大的功能和廣泛的應用場景。 1)核心功能包括圖像編輯、圖層管理、特效製作和色彩調整。 2)適合專業設計師和攝影師,但業餘愛好者可考慮替代品如GIMP。 3)訂閱AdobeCreativeCloud可按需使用,避免一次性高額支出。

Photoshop在創意圖像設計中的核心用途是其強大的功能和靈活性。 1)它允許設計師通過圖層、蒙版和濾鏡將創意轉化為視覺現實。 2)基本用法包括裁剪、調整大小和顏色校正。 3)高級用法如圖層樣式、混合模式和智能對象可創建複雜效果。 4)常見錯誤包括圖層管理不當和濾鏡使用過度,可通過整理圖層和合理使用濾鏡解決。 5)性能優化和最佳實踐包括合理使用圖層、定期保存文件和使用快捷鍵。

Photoshop在網頁設計中可用於創建高保真原型、設計UI元素和模擬用戶交互。 1.使用圖層、蒙版和智能對象進行基礎設計。 2.通過動畫和時間線功能模擬用戶交互。 3.利用腳本自動化設計過程,提高效率。

之前的文章《一步一步教你使用ps將盤子圖片添加印花效果(收藏)》中,給大家介紹了一種小技巧,怎麼使用ps將盤子圖片添加印花效果。下面本篇文章給大家介紹怎麼利用ps筆刷給字體添加裂紋效果,我們一起看看怎麼做。

在Photoshop中,可以通過圖層樣式和濾鏡創建文字效果。 1.創建新文檔並添加文字。 2.應用圖層樣式如陰影和外發光。 3.使用濾鏡如波浪效果,並添加斜面和浮雕效果。 4.使用蒙版調整效果範圍和強度,以優化文字效果的視覺衝擊力。

摳圖是將圖像中的背景部分移除,留下主體的過程。常見的摳圖方法包括:手動摳圖:使用圖像編輯軟件手動勾勒主體邊緣。自動摳圖:使用軟件自動識別主體,將其從背景中分離。利用第三方摳圖工具:使用專門的工具進行摳圖操作。通道摳圖:利用圖像的通道進行分割,選擇與主體顏色差異明顯的通道進行操作。

可以使用在線工具、圖像編輯軟件、視頻編輯軟件、水印去除應用程序。具體方法包括:使用在線工具,使用克隆圖章工具、仿製圖章工具和修復畫筆工具,使用模糊工具、裁剪工具和內容感知填充工具,以及使用水印去除應用程序。在去除水印之前,請確保您有權這樣做。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

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

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

Dreamweaver Mac版
視覺化網頁開發工具

MantisBT
Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

SAP NetWeaver Server Adapter for Eclipse
將Eclipse與SAP NetWeaver應用伺服器整合。

VSCode Windows 64位元 下載
微軟推出的免費、功能強大的一款IDE編輯器

PhpStorm Mac 版本
最新(2018.2.1 )專業的PHP整合開發工具