什么是Surface
Handle onto a raw buffer that is being managed by the screen compositor.
Surface是一个raw buffer的句柄,我们可以通过它在raw buffer上进行绘制。
对应到代码其实就是可以通过Surface获得一个Canvas:
Canvas canvas = mSurface.lockCanvas(null);
//使用Canvas进行绘制
mSurface.unlockCanvasAndPost(canvas);
SurfaceView中的SurfaceHolder就持有一个Surface:
SurfaceHolder.getSurface();
SurfaceTexture
SurfaceTexture从Android 3.0(API level 11)加入。和SurfaceView不同的是,它对图像流的处理并不直接显示,而是转为GL外部纹理,因此可用于图像流数据的二次处理(如Camera滤镜,桌面特效等)。
也就是说这个东西不是用来显示给用户看的, 它是一个Texture, 意识是纹理(额~这个词让我想起opengl中的添加纹理 Texture), 可以想象成一个View的中间件。
例:Camera 把视频采集的内容交给 SurfaceTexture, SurfaceTexture 在对内容做个美颜, 然后SurfaceTexture 再把内容交给 SurfaceView。这就是最后呈现给用户视觉上的美颜内容了。
GLSurfaceView
GLSurfaceView是一个继承了SurfaceView类,它是专门用来显示OpenGL的渲染。相比于SurfaceView,GLSurfaceView加入了EGL的管理,并自带了渲染线程(GLThread),能够真正做到让Camera的数据和显示分离。我们就可以在此基础上对视频数据做一些处理,例如美图,增加特效等。
GLSurfaceView使用流程:
1,实现GLSurfaceView.Renderer,主要包含3个抽象的函数:
onSurfaceCreated: GlSurfaceView 创建的时候回调,可以做一些参数初始化操作
onSurfaceChanged:GlSurfaceView尺寸发送变化时回调,例如横竖屏切换
onDrawFrame:此方法频繁回调,我们可以在这个方法里面进行绘制操作
Renderer中的onDrawFrame方法中向SurfaceTexture绘制:
// Construct a new SurfaceTexture to stream images to a given OpenGL texture.
mSTexture = new SurfaceTexture(hTex);
...
//draw to preview screen
GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, hTex);
2,将GLSurfaceView.Renderer设置到GLSurfaceView:
setRenderer(mRenderer);
3,GLSurfaceView内部使用Renderer中的SurfaceTexture构建Surface进行显示
TextureView
与SurfaceView相比,TextureView不会创建新的窗口来显示内容。它是将内容流直接投放到View中,并且可以和其它普通View一样进行移动,旋转,缩放,动画等变化。TextureView必须在硬件加速的窗口中使用.(这应该是前两年使用的少的原因吧,因为并不是所有手机都支持硬件加速得)。
TextureView被创建后不能直接使用,必须要在它被它添加到ViewGroup后,待SurfaceTexture准备就绪才能起作用(看TextureView的源码,TextureView是在绘制的时候创建的内部SurfaceTexture,这个就是上面说的可以对图像流数据进行二次处理的类,也就是说一个TextureView就可以实现图片的滤镜效果了)。
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height) {
//播放器关联surface
if (mSurfaceTexture == null) {
mSurfaceTexture = surfaceTexture;
openMediaPlayer();
} else {
mTextureView.setSurfaceTexture(mSurfaceTexture);
}
}
...
new Surface(mSurfaceTexture); //通过SurfaceTexture创建Surface
对比
TextureView与SurfaceView+SurfaceTexture组合相比可以完成类似的功能(即把内容流上的图象转成纹理,然后输出),且android新一些的版本都是在新线程进行渲染。对于一些类似于坦克大战等需要不断更新画布的游戏来说,SurfaceView绝对是极好的选择。但是比如视频播放器或相机应用的开发,TextureView则更加适合。
网友评论