前言
思路1、貼紙肯定也是需要定位到人臉的
2、找到貼紙需要放置的位置
3、將貼紙紋理和人本身紋理進行融合
實現人臉定位啥的,我就不說了,不清楚的可以去前面的文章看看,主要來看看貼紙是如何貼上去的
1. 建立貼紙的紋理
2. 畫貼紙//opengl 紋理
mtextureid =
newint[1
];//openglutils是個opengl的工具類,具體的前面也有寫
openglutils.
glgentextures
(mtextureid)
; gles20.
glbindtexture
(gles20.gl_texture_2d,mtextureid[0]
);//將bitmap與紋理的id繫結起來
glutils.
teximage2d
(gles20.gl_texture_2d,
0,mbitmap,0)
;//解綁
gles20.
glbindtexture
(gles20.gl_texture_2d,0)
;
在畫貼紙之前,是已經將之前攝像頭那些紋理已經畫上去過了,然後再來畫貼紙。
gles20.
glenable
(gles20.gl_blend)
;//設定貼圖模式
源圖因子 要畫的是源(耳朵)
已經畫好的目標,也就是我們要往哪兒畫,也就是其他filter的影象
原本是什麼樣子,就畫成什麼樣子
_minus_src_alpha,表示用1.0減去源顏色alpha的值來作為因子
gles20.
glblendfunc
(gles20.gl_one,gles20.gl_one_minus_src_alpha)
;因為在opengl中如果不開啟混合模式,就會把之前的紋理覆蓋掉,這裡就不會顯示上乙個紋理了。
什麼是混合?混合就是把某乙個畫素點的位置原來的顏色與將要畫上去的顏色,以某種方式混合在一起,從而達到某種特殊的效果。我們這裡就需要將貼紙的紋理和人臉的紋理進行乙個混合。
glblendfunc的引數設定有多種模式,第乙個引數表示的是源圖因子,也就是我們要畫上去的貼紙,第二個引數是目標因子,也就是我們要把貼紙畫到哪兒去。這兩個引數有多種值:
gl_zero:表示使用0.0作為因子,實際上相當於不使用這種顏色參與混合運算。這個源圖因子使用的是完全使用,也就是貼紙是完全展示出來的,目標因子是用1.0 - 貼紙的alpha值來作為因子的。gl_one: 表示使用1.0作為因子,實際上相當於完全的使用了這種顏色參與混合運算。
gl_src_alpha:表示使用源顏色的alpha值來作為因子。
gl_dst_alpha:表示使用目標顏色的alpha值來作為因子。
gl_one_minus_src_alpha:表示用1.0減去源顏色的alpha值來作為因子。
gl_one_minus_dst_alpha:表示用1.0減去目標顏色的alpha值來作為因子。
下面就是計算出貼紙所要顯示的位置,然後將座標資訊傳遞給著色器
很多都在**裡進行了注釋,應該都可以看得懂,下面就看一下效果圖吧~~//畫耳朵,是需要往人臉上畫,不是全屏畫
float x = mface.landmarks[0]
;float y =mface.landmarks[1]
;//轉換為要畫到螢幕上的寬、高
x = x / mface.imgwidth * moutputwidth;
y = y/ mface.imgheight * moutputheight;
//貼紙需要顯示的位置
//1.需要顯示到螢幕上的x座標,2.y座標
//3.需要顯示的貼紙的寬 4.高,這兩個引數需要不斷的除錯,然後獲得比較合適的
gles20.
glviewport((
int)x,
(int
)y-mbitmap.
getheight()
/2,(
int)((
float
)mface.width /mface.imgwidth * moutputwidth)
,mbitmap.
getheight()
);les20.
glbindframebuffer
(gles20.gl_framebuffer,mframebuffers[0]
);gles20.
gluseprogram
(mglprogramid)
;//傳遞座標
mglvertexbuffer.
position(0
);gles20.
glvertexattribpointer
(vposition,
2, gles20.gl_float,
false,0
, mglvertexbuffer)
; gles20.
glenablevertexattribarray
(vposition)
; mgltexturebuffer.
position(0
);gles20.
glvertexattribpointer
(vcoord,
2, gles20.gl_float,
false,0
, mgltexturebuffer)
; gles20.
glenablevertexattribarray
(vcoord)
;//啟用紋理,傳遞紋理給著色器
gles20.
glactivetexture
(gles20.gl_texture0)
; gles20.
glbindtexture
(gles20.gl_texture_2d,mtextureid[0]
);gles20.
gluniform1i
(vtexture,0)
;//畫畫
gles20.
gldrawarrays
(gles20.gl_********_strip,0,
4);// 解綁紋理
gles20.
glbindtexture
(gles20.gl_texture_2d,0)
;//解綁framebuffer
gles20.
glbindframebuffer
(gles20.gl_framebuffer,0)
;//最後使用完畢以後需要關閉這個融合
gles20.
gldisable
(gles20.gl_blend)
;
效果圖就差不多是這樣的效果,是因為我手機問題所有才模糊不清楚的,前置攝像頭完成沒有問題的。
Android OpenGL ES 開發入門
本系列文章圍繞關於使用opengl es繪圖的android開發者文件為主線,結合opengl程式設計指南來講述android opengl es開發入門。如果你沒有opengl相關知識,在閱讀opengl es demo 時,可能對圖形的繪製過程不太理解,以至於看完之後,也不知道如何繪製圖形。出於...
Android OpenGLES濾鏡開發之大眼效果
前言 在很多美顏相機啊,抖音啊,都會有一些放大眼睛的效果,今天就來實現如何放大眼睛。思路1 首先使用opencv定位到人臉 2 根據定位到的人臉去檢測人臉關鍵點,進而獲取到人眼睛的位置。3 根據眼睛位置,對眼睛進行放大。實現定位人臉 人臉的定位追蹤,在之前文章中已經寫過opencv實現人臉追蹤 當時...
Android OpenGL ES之新增動作
本文譯自 在螢幕上繪製物件是opengl的最基本功能,你可以使用其他的android圖形框架類,如 canvas 和drawable 物件來完成這些功能。opengles提供了一些用於在三維空間中移動和變換被繪製的物件的能力,以及其他的建立良好使用者體驗的獨特方式。在本文中,你需要使用前面幾篇博文中...