美文网首页OpenGLopengl
Android基于Shader的图像处理(13)-相机分屏预览

Android基于Shader的图像处理(13)-相机分屏预览

作者: andev009 | 来源:发表于2018-12-26 17:17 被阅读40次

    完整代码查看# AndroidShaderDemo下的SplitScreenOneActivity
    想要的效果如下,上下两个屏幕显示相机预览图像:

    split_sreen1.jpg

    这里给出分屏预览的一种方式,在布局里使用GLSurfaceView和SurfaceView两个View分别展示相机预览,缺点是录制视频时不能保持画面的分屏特效,如果要想录制时也要分屏,那么分屏后的画面应该在一张图片纹理上,这个以后再说,这里先看两个View展示的效果。

    在看这篇之前,最好先看之前的Camera开发Android java层封装EGL

    分屏显示原理是,GLSurfaceView通过SurfaceTexture接收相机传来的数据显示预览图像,这时预览图像是个纹理,把纹理传给SurfaceView,这样就达到分屏显示的效果。当然因为SurfaceView没有OpenGL的运行环境,还要封装个离屏Render。
    GLSurfaceView怎么显示相机预览图像就不重复了,重点看第二步,把纹理传给SurfaceView显示。
    首先要为SurfaceView建立渲染线程,HandlerThread可以帮忙,简化不少工作。

    handlerThread = new HandlerThread("preview");
    handlerThread.start();
    previewHandler = new Handler(handlerThread.getLooper());
    

    之后就可以通过previewHandler来post渲染线程的指令了。
    在GLSurfaceView的render回调里,初始化SurfaceView的Callback:

    surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder surfaceHolder) {
                previewHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        offScreenRender = new OffScreenRender(eglContext, surfaceView.getHolder().getSurface());
                        }
                    });
            }
             ......
    }
    

    这里在preview线程里生成一个offScreenRender离屏render,render有了,下面在相机每帧回调时取得纹理,用offScreenRender画出来:

    @Override
    public void onFrameAvailableCallback(final VideoFrameData frameData) {
        previewHandler.post(new Runnable() {
            @Override
            public void run() {
                if(offScreenRender != null){
                    offScreenRender.draw(frameData.getFilter(), frameData.getMatrix(), frameData.getTextureId()
                        ,frameData.getTimestamp());
                    }
            }
        });
    }
    

    可见offScreenRender做了主要工作,GLSurfaceView和SurfaceView共享一个EGLContext:
    1.建立OpenGL环境
    2.发送OpenGL渲染指令
    建立OpenGL环境的工作用到了之前的Android java层封装EGL,这里不再累述,重点是把SurfaceView的Surface传递给EglCore,这样EglCore才知道往哪里绘制。

    发送OpenGL渲染指令封装成了:

    public void draw(CameraInputFilter cameraInputFilter, float[] matrix, int textureId, long time) {
        cameraInputFilter.onDrawFrame(textureId);
        offSreenSurface.swapBuffers();
    }
    

    这里主要关注其中两个参数cameraInputFilter和textureId,textureId就是传来的纹理,cameraInputFilter这里直接显示,当然这里也可以做些特效,这样分屏后,上下两个画面显示就不一样了。

    相关文章

      网友评论

        本文标题:Android基于Shader的图像处理(13)-相机分屏预览

        本文链接:https://www.haomeiwen.com/subject/pixklqtx.html