十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專(zhuān)業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
我覺(jué)得安卓系統(tǒng)值得推薦的濾鏡app有激萌相機(jī),快拍,美圖秀秀等等。這些app都帶有比較全面的濾鏡,而且,相對(duì)來(lái)說(shuō)質(zhì)量都比較高,其實(shí)是新手也能拍出時(shí)尚大片的感覺(jué)。說(shuō)道美顏和濾鏡,我覺(jué)得愛(ài)拍是最強(qiáng)大的,可以將你完全變成另一個(gè)人,它有多種調(diào)節(jié)方式,有無(wú)極調(diào)光和柔光三色不管是直播還是拍攝,都能起到很好的效果,就像是愛(ài)拍上的一個(gè)男博主,利用美顏和濾鏡把自己變成一個(gè)很好看的女生一樣。
網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專(zhuān)注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、成都微信小程序、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了舞鋼免費(fèi)建站歡迎大家使用!
Android Paint之顏色過(guò)濾器
Paint之shader(圖像渲染)
Paint之PathEffect(路徑效果)
Paint API之—— MaskFilter(面具)
android之繪圖工具類(lèi)詳解
Paint API之—— Xfermode與PorterDuff全面詳解
Paint API之—— Xfermode與PorterDuff詳解(三)動(dòng)畫(huà)效果
Paint枚舉、常量值、陰影效果、字體
上節(jié)我們學(xué)習(xí)了MaskFilter(面具),用它的兩個(gè)子類(lèi)BlurMaskFilter弄了下模糊效果,EmbossMaskFilter 弄了下浮雕效果,而本節(jié)我們來(lái)學(xué)習(xí)的是另一個(gè)API—— ColorFilter (顏色過(guò)濾器),和MaskFilter一樣, 我們并不直接使用該類(lèi),而是使用該類(lèi)的三個(gè)子類(lèi):
本節(jié)我們就來(lái)學(xué)習(xí)下第一個(gè)ColorMatrixColorFilter的使用吧,打開(kāi)ColorMatrixColorFilter的文檔,
大概說(shuō)的是:通過(guò)一個(gè)4 x 5的顏色矩陣來(lái)變換顏色,可以修改像素的飽和度,將YUV轉(zhuǎn)換成RGB等! 而構(gòu)造方法中的ColorMatrix就是顏色矩陣,也是我們學(xué)習(xí)的核心,下面聽(tīng)我一一道來(lái)!
RGBA不知道你聽(tīng)過(guò)沒(méi),黃綠藍(lán)知道了吧,光的三基色,而RAGB則是在此的基礎(chǔ)上多了一個(gè)透明度! R(Red紅色) , G(Green綠色) , B(Blue藍(lán)色) , A(Alpha透明度) ;另外要和顏料的三 原色區(qū)分開(kāi)來(lái)哦,最明顯的區(qū)別就是顏料的三原色中用黃色替換了光三基色中的綠色!知道下就好, 有興趣的可自行百度~
中文直譯為“色彩矩陣顏色過(guò)濾器”,我們要先了解什么是色彩矩陣。在Android中圖片是以RGBA像素點(diǎn)的形式加載到內(nèi)存中的,修改這些像素信息需要一個(gè)叫做ColorMatrix類(lèi)的支持,這個(gè)類(lèi)其實(shí)定義的是一個(gè)矩陣,是一個(gè)4x5的float[]類(lèi)型的矩陣:
其中,第一行表示的R(紅色)的向量,第二行表示的G(綠色)的向量,第三行表示的B(藍(lán)色)的向量,最后一行表示A(透明度)的向量,這一順序必須要正確不能混淆!你可能會(huì)問(wèn),那么列呢?我用圖例來(lái)表示一下。
這個(gè)矩陣不同的位置表示的R、G、B、A值,其范圍在0.0F至2.0F之間,1為保持原圖的RGB值。每一行的第五列數(shù)字表示”偏移值“。
何為偏移值?顧名思義當(dāng)我們想讓顏色更傾向于紅色的時(shí)候就增大R向量中的偏移值,想讓顏色更傾向于藍(lán)色的時(shí)候就增大B向量中的偏移值,這是最最樸素的理解,但是事實(shí)上色彩偏移的概念是基于白平衡來(lái)理解的。
什么是白平衡呢?說(shuō)得簡(jiǎn)單點(diǎn)就是白色是什么顏色!在單反的設(shè)置參數(shù)中有個(gè)色彩偏移,其定義的就是白平衡的色彩偏移值,就是當(dāng)你去拍一張照片的時(shí)候白色是什么顏色的,在正常情況下白色是(255, 255, 255, 255)但是“現(xiàn)實(shí)世界中我們是無(wú)法找到這樣的純白物體的”,所以在我們用單反拍照之前就會(huì)拿一個(gè)我們認(rèn)為是白色的物體讓相機(jī)記錄這個(gè)物體的顏色作為白色,然后拍攝時(shí)整張照片的顏色都會(huì)依據(jù)這個(gè)定義的白色來(lái)偏移!而這個(gè)我們定義的“白色”(比如:255, 253, 251, 247)和純白(255, 255, 255, 255)之間的偏移值(0, 2, 4, 8)我們稱(chēng)之為白平衡的色彩偏移。
測(cè)試一下:
我們想要繪制一個(gè)橙色的圓圈,橙色的效果如下:
我們建立一個(gè)矩陣,然后看看效果。
看看效果:
你會(huì)發(fā)現(xiàn)顏色沒(méi)有任何變化,為什么呢?因?yàn)榫仃嚨?表示不做任何變化,也就是保持原樣。我們換一個(gè)下面的矩陣就能看到效果了。
說(shuō)明:如果在eclipse實(shí)時(shí)預(yù)覽的話,它會(huì)提示說(shuō)如果你設(shè)置了這個(gè)屬性,那么eclipse可能無(wú)法準(zhǔn)確的給你一個(gè)預(yù)覽圖。別擔(dān)心,實(shí)際運(yùn)行的時(shí)候就出來(lái)了。
我們來(lái)看看這個(gè)矩陣是怎么計(jì)算的。其實(shí)說(shuō)白了就是矩陣之間的運(yùn)算乘積:
矩陣ColorMatrix的一行乘以矩陣MyColor的一列作為矩陣Result的一行,這里MyColor的RGBA值我們需要轉(zhuǎn)換為[0, 1]。通過(guò)這種計(jì)算我們可以將我們自己設(shè)定的顏色和矩陣的顏色進(jìn)行疊加,創(chuàng)立一個(gè)新的顏色。
再測(cè)試一下:
如果我們用它來(lái)給圖片改顏色,該怎么做呢?下面的例子將會(huì)演示一下。
原本圖片:
加上濾鏡后:
現(xiàn)在我們知道了,ColorMatrixColorFilter和ColorMatrix就是這么個(gè)東西,ColorMatrix類(lèi)里面也提供了一些實(shí)在的方法,比如setSaturation(float sat)設(shè)置飽和度,而且ColorMatrix每個(gè)方法都用了陣列的計(jì)算,如果大家感興趣可以自己去深挖。
顧名思義光照顏色過(guò)濾,這肯定是跟光照是有關(guān)的了。該類(lèi)有且只有一個(gè)構(gòu)造方法:
mul全稱(chēng)是colorMultiply意為色彩倍增,而add全稱(chēng)是colorAdd意為色彩添加,這兩個(gè)值都是16進(jìn)制的色彩值0xAARRGGBB。這個(gè)方法使用也是非常的簡(jiǎn)單。還是拿上面那張圖片來(lái)說(shuō)吧,比如我們想要去掉綠色:
運(yùn)行后你會(huì)發(fā)現(xiàn)綠色確實(shí)是沒(méi)了但是原來(lái)偏綠的部分現(xiàn)在居然成了紅色,當(dāng)LightingColorFilter(0xFFFFFFFF, 0x00000000)的時(shí)候原圖是不會(huì)有任何改變的,如果我們想增加紅色的值,那么LightingColorFilter(0xFFFFFFFF, 0x00XX0000)就好,其中XX取值為00至FF。
PorterDuffColorFilter跟LightingColorFilter一樣,只有一個(gè)構(gòu)造方法:
這個(gè)構(gòu)造方法也接受兩個(gè)值,一個(gè)是16進(jìn)制表示的顏色值這個(gè)很好理解,而另一個(gè)是PorterDuff內(nèi)部類(lèi)Mode中的一個(gè)常量值,這個(gè)值表示混合模式。那么什么是混合模式呢?混合混合必定是有兩種東西混才行,第一種就是我們?cè)O(shè)置的color值而第二種當(dāng)然就是我們畫(huà)布上的元素了!也就是說(shuō)將畫(huà)布上的元素和我們?cè)O(shè)置的color進(jìn)行混合,產(chǎn)生最終的效果。
你可以類(lèi)比為PS中的混合模式,只是PS的圖層混合模式比Android更多更廣泛,但兩者同名混合模式所產(chǎn)生的效果是一樣的,也基于同樣的算法原理這里就不多說(shuō)了。
但是這里要注意一點(diǎn),PorterDuff.Mode中的模式不僅僅是應(yīng)用于圖像色彩混合,還應(yīng)用于圖形混合,比如PorterDuff.Mode.DST_OUT就表示裁剪混合圖。
上一章加載圖片的過(guò)程,在這里就不做贅述。
之前我們通過(guò)YUV數(shù)據(jù)格式的處理知道,只要保留Y的數(shù)據(jù),就是灰度的圖片。但是OpenGL中處理的是RGB格式的數(shù)據(jù),我們要如何去取得灰度圖呢?
我們可以通過(guò)公式,計(jì)算出新的RGB值,就是灰度的圖片了。
我們的目標(biāo)已經(jīng)確定。下面我們需要將片段著色器上的每個(gè)像素的RGB值,通過(guò)上面的公式計(jì)算,裝換成我們的灰度值。
根據(jù)上面的思路,我們需要去改片元著色器。 texture_fragment_shader.glsl
對(duì)比之前的,需要是有如下的修改點(diǎn):
按照之前的想法,我們需要將我們的公式中的系數(shù)傳遞進(jìn)入,就可以完成我們的操作了?;谥暗恼J(rèn)識(shí),我們知道傳遞我們的屬性 uniform 給OpenGL的都是通過(guò)創(chuàng)建數(shù)組,綁定屬性,這一套流程。
與上面的黑白色的處理相似,冷色調(diào)的處理就是單一增加藍(lán)色通道的值,暖色調(diào)的處理可以增加紅綠通道的值。
不管是冷色還是暖色。每個(gè)像素的顏色都和我們傳入的色值相加,產(chǎn)生偏置之后的顏色。同時(shí)還要確保顏色的值合法。如果超過(guò)最大,或者小于最小,就用極限值表示。
還是之前的套路。
紅黃通道增加的結(jié)果
藍(lán)色通道增加的結(jié)果
圖片模糊處理相對(duì)上面的色調(diào)處理稍微復(fù)雜一點(diǎn),通常圖片模糊處理是采集周邊多個(gè)點(diǎn),
然后利用這些點(diǎn)的色彩和這個(gè)點(diǎn)自身的色彩進(jìn)行計(jì)算,得到一個(gè)新的色彩值作為目標(biāo)色彩。
模糊處理有很多算法,類(lèi)似高斯模糊、徑向模糊等等。
最常用的還是高斯模糊。先看一下高斯模糊的原理。
使用正態(tài)分布作為權(quán)重分配模式,對(duì)周?chē)袼厝∑骄档姆绞?,就是高斯模糊?/p>
在圖形上,正態(tài)分布是一種鐘形曲線,越接近中心,取值越大,越遠(yuǎn)離中心,取值越小。
計(jì)算平均值的時(shí)候,我們只需要將"中心點(diǎn)"作為原點(diǎn),其他點(diǎn)按照其在正態(tài)曲線上的位置,分配權(quán)重,就可以得到一個(gè)加權(quán)平均值。
上面的正態(tài)分布是一維的,圖像都是二維的,所以我們需要二維的正態(tài)分布。
二維高斯函數(shù):
有了這個(gè)函數(shù) ,就可以計(jì)算每個(gè)點(diǎn)的權(quán)重了。
為了計(jì)算權(quán)重矩陣,需要設(shè)定σ的值。假定σ=1.5,則 模糊半徑為1 的權(quán)重矩陣,權(quán)重之和等于1,得到最終的權(quán)重矩陣。
對(duì)所有點(diǎn)重復(fù)這個(gè)過(guò)程,就得到了高斯模糊后的圖像。如果原圖是彩色圖片,可以對(duì)RGB三個(gè)通道分別做高斯模糊。
如果一個(gè)點(diǎn)處于邊界,周邊沒(méi)有足夠的點(diǎn),怎么辦?
一個(gè)變通方法,就是把已有的點(diǎn)拷貝到另一面的對(duì)應(yīng)位置,模擬出完整的矩陣。
上面著色器。我們是計(jì)算好了卷積核,直接在 shader 內(nèi)寫(xiě)死應(yīng)用的。
這一小節(jié)的內(nèi)容耗時(shí)比較長(zhǎng)。其實(shí)就是利用OpenGL的shader對(duì)圖像進(jìn)行簡(jiǎn)單的濾鏡處理。
從這節(jié)我們學(xué)習(xí)到
下一章,會(huì)回到Android的內(nèi)容。將OpenGl和Camera結(jié)合在一起。通過(guò)OpenGl來(lái)顯示一個(gè)預(yù)覽的畫(huà)面。
廢話少說(shuō),先舉個(gè)例子
這個(gè)例子其實(shí)在 android端使用ffmpeg給視頻添加圖片水印 里已經(jīng)說(shuō)過(guò)了。
這是一個(gè)給視頻打上圖片水印的命令。
然而,他打的不是一個(gè)普通的水印,而是兩個(gè)。
命令看上去很簡(jiǎn)潔。然而(又是然而),正因?yàn)樗@么簡(jiǎn)潔,所以一開(kāi)始上來(lái)未免搞不清他實(shí)際是什么意思。
來(lái),我們把他拆開(kāi),其實(shí)他由以下部分組成:
1、2、4部分的含義一目了然。3里頭的scale和overlay也是字面的意思,不難理解。然而,-filter_complex濾鏡的參數(shù)結(jié)構(gòu)就不是那么好理解了,比如說(shuō)那一坨[]里頭的東西是什么鬼?
來(lái),一個(gè)個(gè)解釋。
[1:v]這個(gè)里頭兩個(gè)參數(shù),1表示的是操作對(duì)象的編號(hào)。在本例中0就是原始視頻文件input.mp4,1就是image1.png,2就是image2.png,3就是output.mp4。而另一個(gè)參數(shù)v表示操作對(duì)象里的視頻信息。
[img1]是這個(gè)操作過(guò)濾器的名字。(當(dāng)然名字可以隨便起)
所以這頭一句 [1:v]scale=100:100[img1] 的意思就是對(duì)圖片imagei.png進(jìn)行調(diào)節(jié)尺寸的操作,并將這個(gè)操作的結(jié)果命名為img1。后面的[2:v]和[img2]也是一個(gè)意思。
我們繼續(xù),overlay前面 [0:v][img1] 湊一起是什么意思呢。0自然就是指的原始視頻,這句的意思就是將[img1]疊加到0對(duì)象的視頻上。本例中就是把image1.png疊加到input.mp4上。這里需要注意的就是順序:后一個(gè)對(duì)象疊加到前一個(gè)上,后一個(gè)對(duì)象在上層。如果寫(xiě)成 [img1][0:v] ,那相對(duì)本例其實(shí)就是把視頻疊加到圖片imge1.png上。這樣的話一般來(lái)說(shuō)由于視頻通常是全屏,等于用視頻覆蓋了圖片,水印完全看不到了。
好,我們又把這個(gè)操作的結(jié)果命名為[bkg],那么接下來(lái) [bkg][img2] 的意思就很明了了。就是把image2.png再疊加上去,image2.png是在最上層的,如果位置重合的話,他會(huì)遮蓋 image1.png的水印。
于是,事就這樣成了。
1.水印的移動(dòng):
這里需要用到時(shí)間參數(shù)。
比如: overlay=0+t*20:0
這里在x坐標(biāo)上加上了 +t*10 ,于是水印就會(huì)慢慢向右邊移動(dòng)。
2.特定時(shí)間顯示水?。?/p>
這次不僅要用到時(shí)間參數(shù),還要用上條件語(yǔ)句。
if條件語(yǔ)句的基本結(jié)構(gòu)就是
再來(lái)看看計(jì)算表達(dá)式。
這里用到了表達(dá)式 gte(x,y) 。如果x大于等于y則表達(dá)式的值為1,反之為0。
所以 if(gte(t,2),10,NAN) 的意思就是,當(dāng)時(shí)間大于等于2秒時(shí),水印x位置為10,反之不顯示水印。(或者你也可以用 lte 來(lái)判斷“小于或等于”)
要了解所有表達(dá)式的話,可以去啃一下ffmpeg官方文檔的 Expression Evaluation 部分。
參考:
ffmpeg 基本用法大全
ffmpeg Documentation
contrast
n.對(duì)比,對(duì)照; 差異; 對(duì)照物,對(duì)立面; [攝]反差;
[英][?k?ntrɑ:st][美][?kɑ:ntr?st]
contrast
[英][k?n?trɑ:st][美][k?n?tr?st]
vi.對(duì)比; 形成對(duì)照;
vt.使對(duì)照,使對(duì)比; 和…形成對(duì)照;