Android openGl开发详解(二)——通过SurfaceView,TextureView,GlSurfaceView显示相机预览(附Demo)

最近公司在做自定义相机这一块,之前使用的是第三方,后来需求变更,第三方不支持添加动态贴纸,所以只能自己扩展。当然网上有很多例子,但是关于添加动态贴纸的例子几乎找不到,反正我是没找到(欲哭无泪)。当然,现在是所有功能都实现了。觉得openGl还是蛮有意思的,所以从头再梳理一遍,打算整理一个openGl的学习系列。供学习参考。如果对OpenGl没有了解的话,推荐先看Android openGl开发详解(一)——绘制简单图形

这里写图片描述
这里写图片描述

您能从本文了解到如下知识:1. SurfaceView,GlSurfaceView,SurfaceTexture,TextureView的优缺点及区别。2. 如何通过SurfaceView显示Camera预览。 3. 如何通过TextureView显示Camera预览。 4. 如何通过GlSurfaceView处理Camera预览。 5. 总结 6. 源码链接 7.关注打赏

1. SurfaceView,GlSurfaceView,SurfaceTexture,TextureView的优缺点及区别

SurfaceView

继承自View,拥有View的大部分属性,但是由于holder的存在,不能设置透明度。
优点:可以在一个独立的线程中进行绘制,不会影响主线程,使用双缓冲机制,播放视频时画面更流畅
缺点:surface的显示不受View属性的控制,不能将其放在ViewGroup中,SurfaceView不能嵌套使用。

GlSurfaceView

GlSurfaceView继承自SurfaceView类,专门用来显示OpenGL渲染的,简单理解可以显示视频,图像及3D场景这些的。

SurfaceTexture

和SurfaceView功能类似,区别是,SurfaceTexure可以不显示在界面中。使用OpenGl对图片流进行美化,添加水印,滤镜这些操作的时候我们都是通过SurfaceTexre去处理,处理完之后再通过GlSurfaceView显示。缺点,可能会导致个别帧的延迟。本身管理着BufferQueue,所以内存消耗会多一点。

TextureView

同样继承自View,必须在开启硬件加速的设备中使用(保守估计目前百分之九十的Android设备都开启了),TextureView通过setSurfaceTextureListener的回调在子线程中进行更新UI.
优点:支持动画效果。
缺点:在5.0之前在主线程渲染,在5.0之后在单独线程渲染。

TextureView SurfaceView
绘制 稍微延时 及时
内存
动画 支持 不支持
耗电
适用场景(推荐) 视频播放,相机应用 大量画布更新(游戏绘制)

2. 如何通过SurfaceView显示Camera预览。

基本步骤
  1. 在xml文件中设置SurfaceView 。
  2. 实现SurfaceHolder.Callback的回调。
  3. 打开摄像头Camera.open(0);
  4. 设置摄像头相关参数;
  5. 将摄像头数据设置到SurfaceView中,并开启预览。
代码部分
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"  tools:context="com.aserbao.aserbaosandroid.opengl.openGlCamera.simpleCameraOpengl.simpleCamera.CameraSurfaceViewShowActivity">
    <FrameLayout
        android:id="@+id/frame_layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <SurfaceView
                    android:layout_width="match_parent"
                     android:layout_height="match_parent"
                     android:id="@+id/mSurface" />
        <Button
            android:id="@+id/btn_change"
            android:text="给动画,SurfaceView不支持设置透明度"
            android:textAllCaps="false"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"/>
    </FrameLayout>
</android.support.constraint.ConstraintLayout>
/**
 * 使用SurfaceView预览Camera数据
 */
public class CameraSurfaceViewShowActivity extends AppCompatActivity implements SurfaceHolder.Callback {
   
    @BindView(R.id.mSurface)
    SurfaceView mSurfaceView;

    public SurfaceHolder mHolder;
    private Camera mCamera;
    private Camera.Parameters mParameters;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_base_camera);
        ButterKnife.bind(this);
        mHolder = mSurfaceView.getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            // Open the Camera in preview mode
            mCamera = Camera.open(0);
            mCamera.setDisplayOrientation(90);
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        mCamera.autoFocus(new Camera.AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
                if (success) {
                    mParameters = mCamera.getParameters();
                    mParameters.setPictureFormat(PixelFormat.JPEG); //图片输出格式
//                    mParameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);//预览持续发光
                    mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//持续对焦模式
                    mCamera.setParameters(mParameters);
                    mCamera.startPreview();
                    mCamera.cancelAutoFocus();
                }
            }
        });
    }

    
  • 16
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值