天天看點

Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧

一直在情調,時間都是可以自己調節的,不然世界上哪有這麼多牛x的人 今天就開始讀第六章了,算日子也剛好一個月了,一個月就讀一半,這效率也确實有點低了,自己還要加把勁,争取四月底全部看完,第六章講的是android的繪圖機制,應該算是比較核心的東西了,不管什麼功能,最終都是以圖形的方式呈現給使用者的,是以,掌握android的繪圖技巧,可以在讓你設計應用的時候更加的随心所欲,對android的了解更高 基本的繪圖方法,相信讀者都已經很清楚了,我們這章就開始玩進階的東西了

android螢幕相關知識

android繪圖技巧

android圖像處理技巧

surfaceview的使用

主要還是因為android的螢幕确實五花八門,是以在一定程度上的适配問題也是很捉急的,是以我們要對這塊螢幕充分的認識
一塊螢幕通常具備以下的幾個參數

螢幕大小

指螢幕對角線的長度,通常用寸來表示,例如4.7寸,5.5寸

分辨率

分辨率是指實際螢幕的像素點個數,例如720x1280就是指螢幕的分辨率,寬有720個像素點,高有1280個像素點

ppi

每英寸像素又稱為dpi,他是由對角線的的像素點數除以螢幕的大小所得,通常有400ppi就已經很6了
每個廠商的安卓手機具有不同的大小尺寸和像素密度的螢幕,安卓系統如果要精确到每種dpi的螢幕,基本上是不可能的,是以系統定義了幾個标準的dpi
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
這是由于各種螢幕密度的不同,導緻同樣像素大小的長度,在不同密度的螢幕上顯示長度不同,是以相同長度的螢幕,高密度的螢幕包含更多的像素點,在安卓系統中使用mdpi密度值為160的螢幕作為标準,在這個螢幕上,1px = 1dp,其他螢幕則可以通過比例進行換算,例如同樣是100dp的長度,mdpi中為100px,而在hdpi中為150,我們也可以得出在各個密度值中的換算公式,在mdpi中 1dp = 1px, 在hdpi中, 1dp = 1.5px,在xhdpi中,1dp = 2px,在xxhdpi中1dp = 3px,由此可見,我們換算公司 l:m:h:xh:xxh = 3:4:6:8:12
在程式中,我們可以非常友善地對一些機關的換算,下面的代碼給出了一種換算的方法我們可以把這些代碼作為工具類儲存在項目中
其實的density就是前面所說的換算比例,這裡使用的是公式換算方法進行轉換,同時系統也提供了typedvalue幫助我們轉換
是由于畫筆功能的不一樣,再結合各種不同的繪圖api,這樣任意組合就可以實作不同的繪圖效果,比如同樣是矩形設定paint就style可以畫出空心或者實心,我們來看看rectview
運作起來就是
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
xml在安卓系統中可不僅僅是java中的一個布局檔案配置清單,在安卓開發者的手頭上他甚至可以變成一張畫,一幅畫,android開發者給xml提供了幾個強大的屬性
在xml中使用bitmap很簡單
通過這樣引用圖檔就可以将圖檔直接轉化成bitmap讓我們在程式中使用
通過shape可以繪制各種圖形,下面展示一下shape的參數
shape可以說是xml繪圖的精華所在,而且功能十分的強大,無論是扁平化,拟物化還是漸變,都是十分的ok,我們現在來做一個陰影的效果
看效果
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
layer是在photoshop中是非常常用的功能,在android中,我們同樣可以實作圖層的效果
selector的作用是幫助開發者實作靜态view的回報,通過設定不同的屬性呈現不同的效果
這一方法可以幫助開發者迅速制作view的回報,通過配置不同的觸發事件,selector會自動選中不同的圖檔,特别是自定義button的時候,而我們不再使用原生單調的背景,而是使用selector特别制作的背景,就能完美實作觸摸回報了 通常情況下,上面提到的這些方法都可以共同實作,下面這個例子就展示了在一個selector中使用shape作為他的item的例子,實作一個具體點選回報效果的,圓角矩形的selector,代碼如下
我們來看一下效果圖
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
在學完android的基本繪圖之後我們來講解一下常用的繪圖技巧
canvas作為繪制圖形的直接對象,提供了一下幾個非常有用的方法

canvas.save()

canvas.restore()

canvas.translate()

canvas.roate()

首先,我們來看一下前面兩個方法 在講解這兩個方法之前,首先來了解一下android繪圖的坐标體系,這個其實這個前面已經講了,這裡不贅述,而canvas.save()這個方法,從字面上的意思可以了解為儲存畫布,他的作用就是講之前的圖像儲存起來,讓後續的操作能像在新的畫布一樣操作,這跟ps的圖層基本差不多 而canvas.restore()這個方法,則可以了解為合并圖層,,就是講之前儲存下來的東西合并 而後面兩個方法尼?從字母上了解畫布平移或者旋轉,但是把他了解為坐标旋轉更加形象,前面說了,我們繪制的時候預設坐标點事左上角的起始點,那麼我們調用translate(x,y)之後,則将原點(0,0)移動到(x,y)之後的所有繪圖都是在這一點上執行的,這裡可能說的不夠詳細,最典型的例子是畫一個表盤了,那我們這裡就示範一下畫一個表盤
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
我們先來分析一下這個表盤有什麼?我們可以将他分解

1.儀表盤——外面的大圓盤

2.刻度線——包含四個長的刻度線和其他短的刻度線

3.刻度值——包含長刻度線對應的大的刻度尺和其他小的刻度尺

4.指針——中間的指針,一粗一細兩根

相信如果現實中叫你去畫一個儀表盤的話,你應該也會這樣的步驟去畫,實際上android上的繪圖遠比現實中的繪制十分的相似,與ps的繪圖更家相似,當然,我們在繪制一個複雜的圖形之後,不妨先把思路請清除了 這個示例中,我們第一步,先畫表盤,現在畫個圓應該很輕松了。關鍵在于确定圓心和半徑,這裡直接居中吧
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
下面,我們來畫刻度尺,這個也很簡單,一條線而已,隻要确定兩個端點的位置就可以,第一根線還是比較容易确定的,那後面的我們怎麼去确定尼?那些斜着的我們可以用三角函數去實作計算,但是這其實就是一個很簡單的畫圖,三角函數的運算也要這麼多,我們不經要思考,該怎麼去簡化他尼?其實google已經為我們想好了 我們治國與會覺得這個不好畫,主要是這個角度,那麼如果我們将畫布以中心為原點旋轉到需要的角度尼?每當畫好一根線,我們就旋轉多少級角度,但是下一次劃線的時候依然是第一次的坐标,但是實際上我們把畫布重新還原到旋轉錢的坐标了,所有的刻度線就已經畫好了,通過旋轉畫布——實際上是旋轉了畫圖的坐标軸,這就避免了萬惡的三角函數了,通過這樣一種相對論式的變換,間接簡化了繪圖,這時再去繪制這些刻度,是不是要簡單了,隻需要差別整點和非整點的刻度了
我們看看效果
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
緊接着,我們就可以來繪制兩根針了,我們可以這樣來繪制
這樣運作的效果就和最上面的效果圖一樣了,這裡貼上完整的代碼
android中的繪圖api,很大程度上都來自繪圖的api,特别是借鑒了很多ps的原理,比如圖層的概念,相信看過圖層的也都知道是個什麼樣的,我們畫個圖來分析一下
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
android通過savelayer()方法,savelayeralpha()将一個圖層入棧,使用restore()方法,restoretocount()方法将一個圖層出棧,入棧的時候,後面的所有才做都是發生在這個圖層上的,而出棧的時候,則會把圖層繪制在上層canvas上,我們仿照api demo來
當繪制兩個相交的圓時,就是圖層 接下來将圖層後面的透明度設定成0-255不同值 我們分别示範 127 255 0三個
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
android對于圖檔的處理,最常用的資料結構是位圖——bitmap,他包含了一張圖檔的所有資料,整個圖檔都是由點陣和顔色值去組成的,所謂的點陣就是一個包含像素的矩形,每一個元素對應的圖檔就是一個像素,而顔色值——argb,分别對應透明度紅,綠,藍,這四個通用的分量,他們共同決定了每個像素點顯示的顔色
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
在色彩進行中,我們通常用三個角度描述一張圖檔

色調——物體傳播的顔色

飽和度——顔色的純度,從0-100來進行描述

亮度——顔色的相對,明暗程度

而在android中,系統會使用一個顔色矩陣——colormatrix,來處理這些色彩的效果,android中的顔色矩陣是4x5的數字矩陣,他用來對顔色色彩進行處理,而對于每一個像素點,都有一個顔色分量矩陣來儲存argb值
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧

圖中矩陣a就是一個4x5的顔色矩陣,在android中,他們會以一段一維數組的形式來存儲[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t],則c就是一個顔色矩形分量,在處理圖像中,使用矩陣乘法運算ac處理顔色分量矩陣如下圖

Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
矩陣運算的乘法公式相信大家都線上性代數課程中學過,計算過程如下
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
從這個公式我們可以發現
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
這些是這樣歸類的

第一行的abcde用來決定新的顔色值r——紅色

第二行的fghij用來決定新的顔色值g——綠色

第三行的kimno用來決定新的顔色值b——藍色

第四行的pqrst用來決定新的顔色值a——透明

這樣劃分好各自的範圍之後,這些值就比較慢明确了,不過隻這樣說可能會比較抽象,我們通過幾個小李子不斷的去分析 首先,我們來看一下矩陣變換的計算公式,以r分量為例,計算過程是
如果讓a = 1,b,c,d,e都等于0,那麼計算的結果為r1 = r,是以我們可以建構一個矩陣
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
如果把這個矩陣公式帶入r1 = ac,那麼根據矩陣的乘法運算法則,可以得到r1 = r;是以,這個矩陣通常是用來作為初始的顔色矩陣來使用,他不會對原有顔色進行任何改變 那麼當我們要變換顔色值的時候通常有兩種方法,一個是直接改變顔色的offset,即修改顔色的分量。另一種方法直接改變rgba值的系數來改變顔色分量的值。
從前面的分析中,可以知道要修改r1的值,隻要将第五列的值進行修改即可,即改變顔色的偏移量,其它值儲存初始矩陣的值,如圖所示的顔色矩陣實作了這樣的效果。
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
在上面這個矩陣中,我們修改了r,g,所對應的顔色偏移量,那麼最後的處理結果,就是圖像的紅色綠色分别增加了100,而我們知道,紅色混合綠色的到了黃色,是以最終的顔色處理結果就是讓整個圖檔的色調偏黃色
如果修改顔色分量中的某個系數值而其他隻依然儲存初始矩陣的值。
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
在上面這個矩陣中改變了g分量所對應的系資料g,這樣在矩形運算後g分量會變成以前的兩倍,最終效果就是圖像的色調更加偏綠。
圖像的色調,飽和度,亮度這三個屬性在圖像進行中使用的非常多,是以在顔色矩陣中也封裝了一些api來快速調用這些參數,而不用每次都去計算矩陣的值。下面通過一個執行個體來看看如何通過句正改變圖像的色調,飽和度和亮度。 在android中,系統封裝了一個類——colormatrix,也就是前面所說的顔色矩陣。通過這個類,可以很友善地通過改變矩陣值來處理顔色的效果,建立一個colormatrix對象非常簡單代碼如下。
下面我們來處理不同的色光屬性

色調

安卓安卓系統提供了setrotate()幫助我們設定三個顔色的色調,第一個參數系統分别使用0,1,2來代表red green blue 三個顔色的處理而第二個參數就是需要處理的值了
通過這樣的方法,可以為rgb三個顔色的分量重新設定不同的值了

飽和度

android系統中提供了setsaturation()來設定顔色的飽和度,參數即代表飽和度的值,當飽和度為0的時候是灰色的

亮度

當三原色以相同的比例及及混合的時候,就會顯示出白色,系統也正在使用這個原理來改變一個圖像的亮度,代碼如下,當亮度為零時圖像會變成全黑。
除了單獨使用上面的三種方法來經顔色效果的處理之外,android系統還封裝了矩陣的乘法運算,它提供了postconcat方法來将矩陣的作用效果混合,進而疊加處理效果代碼如下。
在了解了改變色光屬性之後,我們回到現實中的例子,在本例子中,我們通過seekbar來改變不同的數值,并将這些數值作用到對應的矩陣中,最後通過postconcat方法混合處理 滑動seekbar獲得輸入值的代碼如下

**這個例子有機會做單獨介紹,這就不提**

通過前面的分析,我們可以知道調整顔色矩陣可以改變一張圖檔的顔色屬性,圖像處理很大程度上就是尋找處理圖像的顔色矩陣,不僅僅可以通過android系統提供的api完成,我們自己也可以修改 下面我們可以模拟一個4x5的顔色矩陣,通過修改矩陣的值,一來驗證前面所說的改變圖像色彩效果的原理是否正确,二來讓讀者對矩陣産生的作用效果更加清晰和認識

![這裡寫圖檔描述](http://img.blog.csdn.net/20160329223612151)

看下怎麼實作的
這裡我們需要動态的去添加edittext
我們無法再oncreate裡獲得視圖的寬高值,是以通過view的post方法,,在視圖建立完成後獲得其寬高值 接下來,隻需要獲得修改後的edittext值,并将矩陣值設定給顔色矩陣即可,在android中使用一個20的一位數組平頭,通過colormatrix用set方法,将一個數組轉換成colormatrix
最後設定兩個按鈕的點選事件
這裡主要是說一些矩陣達到一些效果,比如

灰階效果

反轉效果

懷舊效果

去色效果

高飽和度

作為更加精确的圖像處理方式,可以通過改變每個像素點的具體argb值,達到處理一張圖檔效果的目的,這裡要注意的是,傳遞進來的原始圖檔是不能修改的,一般根據原始圖檔生成一張新的圖檔來修改 在android中,系統系統提供了bitmap.getpixels()方法來幫我們提取整個bitmap中的像素密度點,并儲存在一個數組中,該方法如下
這幾個參數的具體含義如下:

pixels ——接收位圖顔色值的數組,

offset——寫入到pixels[]第一個像素索引值,

stride——pixels[]中的行間距

x——從位圖中讀取的第一個像素的x坐标

y——從圖中讀取的第一個像素的的y坐标

width——從每一行讀取的像素寬度

height——讀取的行數

通常情況下,可以這樣 接下來,我們可以擷取每一個像素具體的argb值,代碼如下
當擷取到具體的顔色值後,就可以通過相應的算法去修改這個argb值了,進而重構一張圖檔,當然,這些算法是前輩們研究的,總結出來的圖像處理方法,由于我們不是專業的圖像處理人員,是以就直接拿來用了
再通過如下代碼将新的rgba值合成像素點
最後将處理後的像素點重新設定成新的bitmap
這些處理方法同樣是專業人士研究成果,通過特定的算法改變顔色的矩陣 我們先看原圖
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
若在abc三個像素點上,要求b點對應的底片效果算法,代碼如下
實際代碼如下
我們再來看看效果。你叫很驚訝的
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
後面的大多數是相同的,隻有一小部分不同,是以我們隻改算法部分
黑白照片
效果
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
……
我們也了解了老半天的色彩處理效果,接下來我們再來探索一下圖像方面的處理技巧
對于圖像的處理,android系統提供了colormatrix顔色矩陣來幫助我們進行圖像處理,而對于圖像的圖形變換,android系統也可以通過矩陣來幫忙,每個像素點都表達了其xy的資訊,android的變化就是一個3x3的矩陣
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
當使用變換矩陣去處理每一個像素點的時候,與顔色矩陣的算法公司其實是一樣的
通常情況下,會讓g = h = 0,i = 1;這樣使1 = g x x + h x y + i恒成立,是以隻需要關注這幾個參數就行 與色彩變換矩陣的初始化矩陣一樣,圖形變換矩陣也需要一個初始矩陣,很明顯就是對角線元素,其他元素為0的矩陣
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
圖像的變形處理包含以下四類基本變換

translate——平移變換

rotate——旋轉變換

scale——縮放變換

skew——錯切變換

我們先看一張圖
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
平移變換的坐标就如圖,即将每個點的像素點進行平移變換,當p(x0,y0)平移到p(x,y)時,坐标發生了如下的變化
通過計算我們可以發現如下等式
這就是我們前面所說的實作平移的平移公式
選擇變換實際上就是一個點圍繞一個中心旋轉到一個新的點上
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
通過計算,額可以還原以上等式
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
前面是以坐标原點為旋轉中心旋轉變換,如果以任一點0為旋轉中心進行旋轉變換,通常需要以下三個步驟

将坐标原點平移到0點

使用前面講的以坐标原點為中心的旋轉方法進行旋轉變換

将坐标原點還原

通過上述三個步驟,就可以以任一點進行旋轉了
一個像素點是不存在縮放的概念的,但是由于圖像是由很多人像素點組成,如果将每個像素點的坐标都進行相同比例的縮放,最終就會形成讓整個圖像縮放的效果,縮放效果的計算公式
如果寫成矩陣的話
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
通過計算,就可以還原上述等式了
錯切變換(skew)在數學上又稱為shear mapping(可譯為“剪切變換”),或者transvection(縮并),它是一種比較特殊的線性變換,錯切變換的效果就是讓所有的x坐标标尺不變,一般分水準和垂直
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
處置錯切就不畫了 在了解了矩陣變換規律之後,通過類似多彩矩陣中模拟矩陣的例子來模拟變形矩陣,整個代碼與子產品顔色矩陣所使用的代碼基本一緻,在圖形變換,同樣是通過了一個一位數組将一個一位數組轉換為變換矩陣
後面一小部分不寫
與我們當初了解色彩的處理效果時類似,使用了顔色矩陣和像素點處理兩種方式來進行圖像處理,這裡在進行圖像的處理方式也有兩種,即前面講的使用矩陣來進行圖像變換和馬上要使用到的drawbitmapmesh()方法來處理,操作像素塊的原理,該方法如下
這個方法的參數非常的多

bitmap:将要扭曲的圖像

meshwidth:需要的橫向網格數目

meshheight:需要的縱向網格數目

verts:網格交叉點的坐标數組

vertoffset:verts數組中開始跳過的(x,y)坐标對的數目

前面說了,要想使用drawbitmapmesh()的方法先要将突破分成若幹份,是以在圖像各畫n-1條線,将圖檔分成n塊,這裡我來示範一下
接下來,在ondraw()方法中改變交叉點的縱坐标的值,為了實作旗幟飄飄的效果,使用sin x,來改變交叉點的坐标值,使橫坐标不變,将其變化後的值儲存在數組中
然後我們就可以使用了
為了能夠讓圖檔動起來,可以充分利用正弦函數的周期性來實作,在擷取縱坐标的偏移量的時候給函數增加一個周期
而在重繪 d 時候,給k值增加
這裡,每次重繪的時候,通過改變相位來改變偏移量,進而造成一個動态的效果,就好像旗幟在空中飄揚一樣 使用drawbitmapmesh()方法可以建立很多複雜的特效,但是對他的使用也相對來講比較複雜,需要開發者對圖像處理有很深的功底,同時對算法要求比較高,才能做出特效

這一章沒有截圖,原書亂七八糟的例子,也可能是自己渣渣了吧

不管是在我們的世界裡,還是在android的世界裡,要想畫出好的圖檔,就必須賬務畫筆的特效,今天我們就來玩玩這個paint的特殊get
在學習這個東西之前,我們先來看看一張非常經典的圖檔,來自api demo。基本上講porterduffxfermode的都是根據這張圖檔來的
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
途中列舉了16中porterduffxfermode,有點像數學中的集合,主要是一個混合顯示模式 這裡注意了,porterduffxfermode設定兩個圖層交集區域的顯示方法des是先畫的圖像,src是後畫的 當然,這些模式也不是經常的用到,用到最多的事,使用一張圖檔作為另一張圖檔的遮罩,通過控制遮罩層的圖形,來控制下面被遮罩的顯示效果,其中最常用的就是通過dst_in.src_in模式來實作将一個矩形變成圓角圖檔的效果,我們這裡來實作一下
下面我們來做一個比較類似于刮刮卡的效果,其實效果就是兩張圖檔,上面那張一刮就顯示下面的那張看,這個效果同樣我們可以使用porterduffxfermode去實作,我們首先要做的就是初始化一些資料
在這裡我們給paint設定一些屬性,讓他更圓一點,然後我們再監聽觸摸時間
最後隻需要使用dst_in來完善覆寫即可,這裡我把源碼放上來
這裡我們再運作一下
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
這裡唯一要注意的就是使用porterduffxfermode的時候最好把硬體加速給關掉,因為有些不支援
shader又被稱為着色器。渲染器,它可以實作渲染,漸變等效果,android中的shader包括以下幾種

bitmapshader:位圖shader

lineargradient:線性shader

radialgradient:光束shader

sweepgradient:梯形shader

composeshader:混合shader

除了第一個之外,其他的都是比較正常的,實作了名副其實的漸變,渲染效果,而與其他shader的效果不同的是,bitmapshader所産生的是一個圖像,有點類似ps裡面的圖像填充,他的作用是通過paint對畫布進行制定bitmap的填充,填充式有一下幾個模式供選擇。

clamp拉伸——拉伸的是圖檔最後的哪一個像素,不斷重複

repeat重複——橫向,縱向不斷重複

mirror鏡像——橫向不斷翻轉重複,縱向不斷翻轉重複

這幾種模式的含義都非常好了解的,與字面意識基本相同,這裡最常用的是clamp拉伸模式,雖然他會拉伸最後一個像素,但是隻要将突破設定成一個固定的像素,是可以避免的,下面我們來舉個例子;
運作
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
這裡模式是選取的clamp,我們再來看,我們這裡更改為repeat
我們再運作一下
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
很好玩,我們接下來看lineargradient,了解起來就是線性漸變的意思,我們也來寫個例子
我們運作的結果
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
其實這幾種模式都差不多相同,隻是漸變顯示的效果不一樣罷了 其實,這些漸變效果通常會直接使用在程式裡,我們再來用一個倒影的例子來解釋這個原理吧
我們直接預覽
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
要想了解patheffect,還是直接看一張圖比較直覺吧
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
patheffect就是指,用各種筆觸效果繪制路徑,android系統提供的從上到下

cornerpatheffect:拐彎處變圓滑

dashpatheffect:線段上有雜點

pathdashpatheffect:雜點可以設定形狀

composepatheffect:新效果

這樣,我們來做一個簡單的執行個體:
我們再來運作一下
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
android系統提供了view進行繪圖處理, view可以滿足大部分的繪圖需求,但在某些時卻也有些心有餘而力不足,特别是在進行一些開發的時候。 我們知道,view通過重新整理來視圖, android系統通過發出vsync信号來進行螢幕的重繪, 重新整理的間隔時間為i6ms。在16ms内view完成了你所需要執行的所有操作,那麼使用者在視覺上, 就不會産生卡頓的感覺:而如果執行的操作邏輯太多,特别是需要頻繁重新整理的界面上,例如遊戲界面,那麼就塞主線程,進而導緻畫面卡頓,很多時候,在自定義view的log中經常會看見如下示的警告
這些警告的産生,很多情況下就是因為在繪制過程中, 處理邏輯太多造成的為了避免這一問題的産生一 android系統提供了surfacevicw元件來解決這個問題,可以說是view的孿生兄弟,但它與view還是有所不同的,它們的差別主要展現

1.view主要用于自動更新的情況下,而surfacevicw主要适用于被動更新,例如頻繁重新整理

2.view在主線程中重新整理,而surfaceview通常會通過一 個子線程來進行頁面重新整理。

3.view在繪制的時候沒有雙緩沖機制,而surfacevicw在底層實作機制中就已經實作了雙緩沖機制;

總結起來,如果你的自定義view需要頻繁重新整理,或者重新整理時資料處理量比較大,那麼你就可以考慮使用surfacevicw取代view了
surfaceview的使用雖然比view複雜.但是surfaeview在使用時, 有一套使用的模闆代碼,大部分的surfaceview繪圖操作都可以套用這樣的模闆代碼來進行編寫:是以,其實surfaceview的使用更加簡單 通常情況下 使用以下步驟來建立一個surfaceview的模闆。

建立surfaceview

建立自定義的surfaceview,實作它的兩個接口
通過實作它的兩個幾口,就會有三個回調方法
分别對應的是surfaceview的建立,改變和銷毀的過程 對于runnable接口,會實作他的回調

初始化surfaceview

在自定義的surfaceview構造方法中,需要對surfaceview進行出還刷,我們首先要定義三個成員變量
初始化方法就是對回調初始化以及注冊
另外兩個成員變量一canvas和标志位。 對canvas我們已經非常熟悉了,與在view的ondraw()方法中吏用canvas繪圖一樣,在surfaceview中,我們也要使用canvas來進行繪圖,另一個标志位則是用來控制子線程的

使用surfaceview

通過surfaceholder對象的lockcanvas方法,就可以獲得目前canvas繪圖對象,接下來,就可以與在view中進行的繪制操作一樣進行繪制了,不過這裡要注意的是canvas對象還是繼續上次的canvas對象,而不是一 個新的對象。是以,之前的操作都将被保留,如果需要擦除,則可以在繪制前, 通過drawcoloro方法來進行清屏操作 繪制的時候,充分利用surfaceview的回調方法,在surfacecreated方法中開啟子線程進行繪制,而子線程開啟了一個while(misdrawing)的循環來不停的繪制,而在具體的邏輯中,通過lookcanvas()方法擷取canvas對象進行繪制,,整個代碼子產品如下:
以上的代碼基本可以滿足大部分的surfaceview繪制,唯一需要注意的就是繪制的時候mholder.unlockcanvasandpost(mcanvas);放在finally中,來保證每次都能将任務送出
下面我們通過兩個執行個體來玩玩surfaceview
我們運作一下
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
我們再來看下一個例子
我們來實作一個畫闆
這個可好玩多了
Android群英傳筆記——第六章:Android繪圖機制與處理技巧Android群英傳筆記——第六章:Android繪圖機制與處理技巧
好了,到這裡,第六章終于寫完了,我有一種想吐的感覺,太長了,希望大家多支援哈
因為很長,是以用了mac和windows兩個平台寫,ppt和demo有些不完整,不過不影響觀看!

繼續閱讀