hencoder学习自定义view(1)
從hencoder上學習關于 paint的知識
HenCoder Android 開發進階: 自定義 View 1-2 Paint 詳解
關于Paint,有四個最重要的API,分別是
- 顏色
- 效果
- drawText()相關
- 初始化
1、顏色
canvas繪制的內容對顏色有三種處理:
1.1、基本顏色
為像素的基本顏色,根據繪制內容的不同而有不同的控制方式:Canvas的顏色填充類方法drawColor()/RGB()/ARGB()的顏色,是直接寫在參數中的,drawBitmap的顏色是由Bitmap對象直接提供的,除此之外,文字和圖形的顏色繪制就需要paint的額外參數來設置了。
這三個值為透明度和三原色,實際運用setARGB和setColor效果是一樣的
setShader(Shader shader) 設置 Shader
除了給paint直接設置顏色,還可以給paint設置Shader,它是一個著色器,是一套設置顏色的方案。
當設置了Shader后,Paint就不會使用setColor或者setARGB里面的顏色了,而是直接使用Shader中的方案。
設置兩個點和兩種顏色,以這兩個點作為端點,使用兩種顏色的漸變來繪制顏色。比如:
效果如下:
其中前4個參數為2個端點的坐標,兩個顏色為端點散發出的顏色,最后一個變量Shader.TileMode tile有三種模式:CLAMP、MIRROR、REPEAT,從字面意思上可以得出CLAMP是最正常的模式,其次是鏡像最后一個是重復漸變。
就是從圓的中心向外顏色漸變:
前兩個參數為圓心,第三個參數為半徑,第一個顏色為輻射的中心顏色,第二個則為邊緣顏色。效果如下:
3. SweepGradient 掃描漸變
大概是這樣:
效果如下:
沒錯從上面的效果可以看出 使用drawCircle+BitmapShader 和 drawBitmap效果一樣,但是這樣可以繪制出圓形的bitmap,比如說頭像。
就是把兩個Shader混在一起用
PorterDuff.Mode.SRC_OVER:使用了兩個bitmap進行疊加繪制。
PorterDuff.Mode是用來指定兩個bitmap繪制時的顏色策略。它有17種繪制模式,而 SRC_OVER是最正常最常用的繪制策略。
別的模式可以參考官方文檔:官方文檔
1.2、setColorFilter(ColorFilter colorFilter)
為顏繪制設置顏色過濾,為繪制的內容建立一個統一的過濾策略,然后 Canvas的drawXXX()會對每個像素都進行過濾然后繪制出來。在paint中使用setColorFilter方法,ColorFilter并不能直接使用,而是要使用它的三個子類:LightingColorFilter PorterDuffColorFilter 和 ColorMatrixColorFilter。
用來模擬簡單的光照效果
LightingColorFilter的構造方法是LightingColorFilter(int mul, int add),參數中的mul和add都是和顏色格式相同的int值,其中mul用來和目標像素相乘,add用來和目標像素相加。
一個默認的LightingColorFilter,mul值為0xffffff,add值為0x000000,那么對于一個像素,他的計算過程就是:
R' = R * 0xff / 0xff + 0x0 = R // R' = R G' = G * 0xff / 0xff + 0x0 = G // G' = G B' = B * 0xff / 0xff + 0x0 = B // B' = B如果我們將紅色移除,可以把mul值改成 0x00ffff,則R’就計算等于0了。
比如說我們可以把綠色調的更加鮮艷,可以將add改成 0x003000,那么其G’=G+0x30,這時候綠色就更加的鮮艷了~
PorterDuffColorFilter
用一個指定的顏色和一個指定的ProterDuff.Mode來對繪制對象進行合成。和之前的ComposeShader相比的區別就是之前是用Bitmap來進行合成,而這次就只能指定用一種顏色源。
ColorMatrixColorFilter
ColorMatrixColorFilter 使用一個 ColorMatrix 來對顏色進行處理。 ColorMatrix 這個類,內部是一個 4x5 的矩陣:
通過計算,ColorMartix可以要把繪制的像素進行轉化,對于顏色【R,G,B,A】來說,轉化算法是這樣的:
R’ = a*R + b*G + c*B + d*A + e; G’ = f*R + g*G + h*B + i*A + j; B’ = k*R + l*G + m*B + n*A + o; A’ = p*R + q*G + r*B + s*A + t;還可以通過setSatuation(float sat)來進行設置飽和度,具體如何就不說了。
這里有個通過ColorMatrixColorFilter做的開源濾鏡庫StyleImageView
以上就是Paint對顏色的第二層處理:通過setColorFilter(colorFilter)來進行像素過濾從而達到加工顏色的效果。
Paint最后一層處理顏色的方法就是setXfermode,它處理的是 [當顏色遇上View] 的問題。
1.3 setXfermode
“Xfermode"其實就是"Transfer mode”,準確的定義是當你要繪制的內容和Canvas的目標位置的內容應該怎樣結合計算去得出最終的顏色。通俗地說,其實就是要你以繪制的內容作為源圖像,以 View 中已有的內容作為目標圖像,選取一個 PorterDuff.Mode 作為繪制內容的顏色處理方案。就像這樣:
得到的效果是這樣:
另外,從上面的示例代碼可以看出,創建 Xfermode 的時候其實是創建的它的子類 PorterDuffXfermode。而事實上,Xfermode 也只有這一個子類。
使用Xfemode時我們要注意兩點:
我們實際上在不做處理時使用上述的代碼并不能直接得到那么理想的結果,而是:
這是因為在第二步畫圓的時候,和正方形一起進行計算并不是這個圓,而是這個帶圓的view,而且因為View的底色并不是默認的透明色,所以導致這些底色也參與了計算,這個時候我們需要開啟離屏緩存 (Off-screen Buffer) ,先讓繪制的內容在屏幕之外繪制好,最后再貼回view中:
使用離屏緩存有兩種方式:
(1)Canvas.saveLayer()
可以做短時間的離屏緩沖。
(2)View.setLayerType()
View.setLayerType() 是直接把整個 View 都繪制在離屏緩沖中。 setLayerType(LAYER_TYPE_HARDWARE) 是使用 GPU 來緩沖, setLayerType(LAYER_TYPE_SOFTWARE) 是直接用一個 Bitmap 來緩沖。
使用Xfermode來繪制內容,除了注意使用離屏緩沖,還要注意控制它的透明區域不要太小,要讓它足夠覆蓋到要和它結合繪制的內容。否則很容易得到你不想要的,比如:
到這里,Paint的第一類API,關于顏色的設置到這里就講完了,Paint對繪制內容的著色主要包括三層,第一層是通過setColor等api像素進行直接上色,第二類是通過setColoerFilter來對像素進行過濾,就和我們平時相機用到的濾鏡似的,最后通過Xfermode來對繪制中出現相遇別的view的時候做一個顏色的處理。
總結
以上是生活随笔為你收集整理的hencoder学习自定义view(1)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CF Round410 D. Mike
- 下一篇: 最新xml注释顶格问题的解决方法