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等接口。


原創不易,若是您以爲好,能夠分享此公衆號給你更多的人。