Camera 预览之SurfaceView、TextureView、GLSurfaceView(二)


随着项目一步步往前推动SurfaceView没法知足要求了,由于须要对预览视图进行变换处理,TextureView就被呼唤出来了,看下官网对TextureView的解释:app

A TextureView can be used to display a content stream. Such a content stream can for instance be a video or an OpenGL scene. The content stream can come from the application's process as well as a remote process.ide

TextureView can only be used in a hardware accelerated window.函数

简单理解:动画

TextureView能够用来显示内容流。这样一个内容流能够视频或者OpenGL的场景。内容流能够来自本应用程序以及远程进程。this

Textureview必须在硬件加速开启的窗口中。spa

与SurfaceView相比,TextureView不会建立一个单独的窗口,这使得它像普通的View能够执行一些变换操做,好比移动、动画等。视频

使用TextureView很简单,你须要使用的一个SurfaceTexture,SurfaceTexture能够用于呈现内容。SurfaceTexture能够理解为一个画布,Textureview是画布里真正渲染的内容。我将以前的SurfaceView代码改造了一下。blog

public class CameraTexturePreview extends TextureView implements TextureView.SurfaceTextureListener {
    private final String TAG = "CameraTexturePreview";
    Context mContext;  
    SurfaceTexture mSurface;
    public CameraTexturePreview(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.mContext = context;  
        this.setSurfaceTextureListener(this);  
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,
            int height) {
        Log.i(TAG, "onSurfaceTextureAvailable()");
        this.mSurface = surface;  
    }

    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,
            int height) {
        Log.i(TAG, "onSurfaceTextureSizeChanged()");  
    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        Log.i(TAG, "onSurfaceTextureDestroyed()");  
        CameraWrapper.getInstance().doStopCamera();
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {
 
    }

    public SurfaceTexture getSurfaceTexture() {
        return this.mSurface;
    }
}
CameraTexturePreview继承制TextureView,TextureView实现TextureView.SurfaceTextureListener接口,获取用于渲染内容的SurfaceTexture。当SurfaceTexture准备好了的时候会调用onSurfaceTextureAvailable。继承

接下来看下如何渲染,和上一篇代码差很少,就不全贴了,贴出差别部分。接口

设置一些参数信息

private void initViewParams() {
        LayoutParams params = mCameraTexturePreview.getLayoutParams();
        DisplayMetrics displayMetrics = this.getResources().getDisplayMetrics();  
        int screenWidth = displayMetrics.widthPixels;  
        int screenHeight = displayMetrics.heightPixels;
        params.width = screenWidth;  
        params.height = screenHeight;  
        Log.i(TAG, "screenWidth: " + screenWidth);
        Log.i(TAG, "screenHeight: " + screenHeight);
        this.mPreviewRate = (float)screenHeight / (float)screenWidth;
        mCameraTexturePreview.setLayoutParams(params);
    }

    @Override
    public void cameraHasOpened() {
        SurfaceTexture surface = this.mCameraTexturePreview.getSurfaceTexture();
        CameraWrapper.getInstance().doStartPreview(surface, mPreviewRate);
        
    }

重点看下doStartPreview函数:

    public void doStartPreview(SurfaceTexture surface, float previewRate) {
        Log.i(TAG, "doStartPreview()");
        if (mIsPreviewing) {
            this.mCamera.stopPreview();
            return;
        }

        try {

            this.mCamera.setPreviewTexture(surface);
        } catch (IOException e) {
            e.printStackTrace();
        }

        ........省略部分代码

         this.mCamera.startPreview();


    }

将准备好的SurfaceTexture设置给setPreviewTexture,进行数据预览。你能够在预览的时候对CameraTexturePreview进行一些变换处理,能够调用setAlpha,setRotation等接口。


原创不易,若是您以为好,能够分享此公众号给你更多的人。