換個思路更簡單 方便好用的文字描邊效果實現方法

2021-06-06 18:15:20 字數 2955 閱讀 9725

當我們需要在色彩豐富的上顯示文字的時候,由於背景色變化的關係,文字往往不能清晰呈現。就像很多早期電影使用純白色字幕,在藍天白雲的畫面下常常看不清楚字幕。這時候,我們就需要文字描邊這種能夠突出顯示文字的效果了,就像這樣。

(動畫截圖 by wong shao voon)

那麼,怎樣實現這樣的效果呢?下面我粗略介紹下目前常見的幾種方法。最後介紹我構思的一種簡單而實用的實現方法。

一般方法

第一種思路:文字即

將textblock 轉換為writeablebitmap

對writeablebitmap 的pixels 進行迴圈,判斷每乙個畫素點的值最終達到描邊的效果。

參考《silverlight字型描邊》

野比點評:

這種思路將文字轉為,根據判斷上每個畫素點,效率低下,最終效果簡單,如下圖所示。

第二種思路:畫素著色器

該方法基本思路為:假定只會對textblock應用畫素著色器,那麼textblock是乙個矩形,文字所在畫素的 alpha分量必定大於0,否則必定是透明畫素。判斷如果當前畫素的上,下,左,右任意乙個畫素不透明,則說明本畫素需要被描邊,否則就輸出文字顏色。由於需要知道相鄰畫素,所以還需要傳入textblock的actualwidth和actualheight。 這樣, 當前位置的 x+ 1/width 就是相鄰畫素的座標,就可以用tex2d函式來提取它的顏色值。還需要輸入描邊的顏色,還有文字的顏色。

參考《silverlight畫素著色器編寫簡明指南 附送文字描邊效果》

野比點評:

仍然是乙個「大炮打蚊子」的思路,將文字進行逐畫素的處理。和思路1唯一的區別在於使用了畫素著色器,讓把部分工作交給gpu來完成,「看起來」很高效很快速。但是如果禁用了硬體加速呢?就變成和1一樣了。下面是該方法的效果截圖。

第三種思路:gdi+路徑繪圖

這種方法不再是逐畫素處理了。其基本思路是將文字字串新增到gdi+的繪圖路徑中(graphicspath),然後再drawpath()。利用不同的筆刷,這種方法可以「畫」出非常華麗的描邊效果,就像這樣。

野比點評:

這是擴充套件性最好的方法。由於利用了gdi+的高階特性,所以可以利用不同的筆刷如紋理、漸變,以及多次繪圖等方法做出非常精美的描邊、陰影效果。唯一的遺憾就是**量較大(比前面2種要少很多了)。

參考文章《c# 水印+文字描邊+發光文字。看示圖及demo》

關於該方法的高階效果設計,參考《outline text》一文(code project「best c++/mfc article of sep 2009」比賽獲獎文章)。

野比的簡易方法

又到了野比的偷懶時間。

看了前面幾種設計思路後,你有沒有一頭霧水的感覺?或者眼花繚亂的感覺?難道我們只有這樣實現嗎?需要「描邊」文字,就一定要「描」嗎?

其實完全沒有必要。曾經我在山寨safari時,介紹過一種簡單的通過重複繪製文字實現高光效果的方法(參見《一步一步玩控制項:tabcontrol——從製作山寨safari窗體開始》)。

如下圖所示。當底層文字和頂層文字相差1px時,就會呈現出不同的陰影/高光效果。那麼我們如果把這個思路拓展下,把上、下、左、右四個方向的偏差結合到一起,就會像下圖最後顯示的效果一樣,得到了「描邊」文字的效果。

接下來在gdi+裡面實現它。 

// code by conmajia

// txtpoint是繪製文字的定位點

txtpoint.offset(-1, 0); // 繪製左背景文字

e.graphics.drawstring(this.text, this.font, backbrush, txtpoint);

txtpoint.offset(2, 0); // 繪製右背景文字

e.graphics.drawstring(this.text, this.font, backbrush, txtpoint);

txtpoint.offset(-1, -1); // 繪製下背景文字

e.graphics.drawstring(this.text, this.font, backbrush, txtpoint);

txtpoint.offset(0, 2); // 繪製上背景文字

e.graphics.drawstring(this.text, this.font, backbrush, txtpoint);

txtpoint.offset(0, -1); // 定位點歸位

// 繪製前景文字

e.graphics.drawstring(this.text, this.font, forebrush, txtpoint);

下面請欣賞效果

結語

很多時候,我們遇到問題,不一定需要完全跟著問題走。就像這次,我們需要「描邊」,但誰說的,我們非得要「描」邊呢?我們要的只是效果,而不是過程,所以要跳出問題表象的禁錮,就能獲得更加寬廣的視野。

(全文完)

乙個簡單方便又好用的員工管理系統應該具備以下這三點

我有一款好用的員工管理軟體vika維格表推薦給你,我一直都是使用它來管理員工資訊。簡單的操作和優秀的視覺化介面是人員管理中最核心的內容。作為乙個管理系統,如果只能用來管理員工資訊那作用就顯得非常的小,vika維格表不僅僅能管理員工資訊,還能管理各種的專案。也就是說,維格表乙個管理軟體就能抵市面上多個...

vim簡單方便的命令集錦

1 統計m到n行中 字串 出現的次數 m,ns 字串 gn只需要修改m,n的值,並將 字串 替換為待統計的字串即可 2 另外乙個方法,統計 字串 在當前編輯檔案出現的次數 s 字串 ng 1 跳到文字的最後一行 按 g 即 shift g 2 跳到最後一行的最後乙個字元 先重複1的操作即按 g 之後...

asp匯出excel檔案最簡單方便的方法

由於excel軟體能識別table格式的資料,所以asp只需要輸出table格式的html 同時設定好contenttype,增加儲存為附件的響應頭即可將輸出的html 儲存為xls檔案。asp匯出excel檔案源 如下 複製 如下 response.addheader content dispos...