Android之TextureView淺析

來源:互聯網
上載者:User

標籤:tracking   檢查   官方   add   ict   等等   callback   tar   apk   

近期,在改動Android4.4的原生相機Camera2,非常習慣的去尋找SurfaceView,結果任憑我使用grep還是ack。都無法搜尋到SurfaceView,最後還是通過代碼CameraActivity-->CameraModule-->PhotoUI-->R.layout.photo_module找到,原來是使用了TextureView。

不是非常瞭解此控制項。百度之。在官方API文檔中找到此控制項:

http://android.toolib.net/reference/android/view/TextureView.html

官方文檔大概的意思是:

TextureView能夠用來顯示內容流。這樣一個內容流比如能夠視頻或者OpenGL的情境。內容流能夠來自本應用程式以及其它進程。

Textureview必須在硬體加速開啟的表單中。

與SurfaceView相比。TextureView不會建立一個單獨的表單,這使得它能夠像一般的View一樣運行一些變換操作,比方移動、動畫等等,比如,你能夠通過調用myView.setAlpha(0.5f)將TextureView設定成半透明。

使用TextureView非常easy:你須要使用的就是SurfaceTexture。SurfaceTexture能夠用於呈現內容。



以下是我寫一個小範例來示範怎樣渲染相機預覽到TextureView。在官方文檔範例的基礎上略微修改了一下:

main.xml:


<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="horizontal" >    <FrameLayout        android:id="@+id/camera_preview"        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_weight="1" />    <Button        android:id="@+id/button_capture"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:text="Capture" /></LinearLayout>

CameraPreview.java:

import java.io.IOException;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.SurfaceTexture;import android.hardware.Camera;import android.view.TextureView;@SuppressLint("NewApi")public class CameraPreview extends TextureView implements        TextureView.SurfaceTextureListener {    private Camera mCamera;    private TextureView mTextureView;    public CameraPreview(Context context , Camera camera) {        super(context);        mCamera = camera;        // TODO Auto-generated constructor stub    }    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width,            int height) {//        mCamera = Camera.open();        try {            mCamera.setPreviewTexture(surface);            mCamera.startPreview();        } catch (IOException ioe) {            // Something bad happened        }    }    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width,            int height) {        // Ignored, Camera does all the work for us    }    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {        mCamera.stopPreview();        mCamera.release();        return true;    }    public void onSurfaceTextureUpdated(SurfaceTexture surface) {        // Invoked every time there's a new Camera preview frame    }}

CameraTest.java:

import java.io.File;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.text.SimpleDateFormat;import java.util.Date;import android.annotation.SuppressLint;import android.app.Activity;import android.content.Intent;import android.hardware.Camera;import android.hardware.Camera.PictureCallback;import android.os.Bundle;import android.os.Environment;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.FrameLayout;import android.widget.Toast;import com.example.mycamera.R.id;@SuppressLint("NewApi")public class CameraTest extends Activity {    public static final int MEDIA_TYPE_IMAGE = 1;    public static final int MEDIA_TYPE_VIDEO = 2;    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;    private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;    private Camera mCamera;    private CameraPreview mPreview;    private static final String TAG = "ERROR";    private PictureCallback mPicture = new PictureCallback() {        @Override        public void onPictureTaken(byte[] data, Camera camera) {            File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);            if (pictureFile == null) {                Log.d(TAG,                        "Error creating media file, check storage permissions: "                                + "e.getMessage()");                return;            }            try {                FileOutputStream fos = new FileOutputStream(pictureFile);                fos.write(data);                fos.close();            } catch (FileNotFoundException e) {                Log.d(TAG, "File not found: " + e.getMessage());            } catch (IOException e) {                Log.d(TAG, "Error accessing file: " + e.getMessage());            }        }    };    @Override    protected void onCreate(Bundle savedInstanceState) {        // TODO Auto-generated method stub        super.onCreate(savedInstanceState);        setContentView(R.layout.main);        // 建立Camera執行個體        mCamera = getCameraInstance();        // 建立Preview view並將其設為activity中的內容        mPreview = new CameraPreview(this, mCamera);        mPreview.setSurfaceTextureListener(mPreview);        //設定渾濁        mPreview.setAlpha(0.5f);        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);        // preview.setAlpha(0.0f);        preview.addView(mPreview);        // 在Capture按鈕中增加listener        Button captureButton = (Button) findViewById(id.button_capture);        captureButton.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                // 從網路攝影機擷取圖片                mCamera.takePicture(null, null, mPicture);            }        });    }    /** 安全擷取Camera對象執行個體的方法 */    public static Camera getCameraInstance() {        Camera c = null;        try {            c = Camera.open(); // 試圖擷取Camera執行個體        }        catch (Exception e) {            // 網路攝影機不可用(正被佔用或不存在)        }        return c; // 不可用則返回null    }        /** 為儲存圖片或視頻建立File */    private static File getOutputMediaFile(int type) {        // 安全起見,在使用前應該        // 用Environment.getExternalStorageState()檢查SD卡是否已裝入        File mediaStorageDir = new File(                Environment                        .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),                "MyCameraApp");        // 假設期望圖片在應用程式卸載後還存在、且能被其他應用程式共用,        // 則此儲存位置最合適        // 假設不存在的話,則建立隱藏檔夾        if (!mediaStorageDir.exists()) {            if (!mediaStorageDir.mkdirs()) {                Log.d("MyCameraApp", "failed to create directory");                return null;            }            Log.d("MyCameraApp", "failed to create directory");        }        // 建立媒體檔案名稱        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")                .format(new Date());        File mediaFile;        if (type == MEDIA_TYPE_IMAGE) {            mediaFile = new File(mediaStorageDir.getPath() + File.separator                    + "IMG_" + timeStamp + ".jpg");        } else if (type == MEDIA_TYPE_VIDEO) {            mediaFile = new File(mediaStorageDir.getPath() + File.separator                    + "VID_" + timeStamp + ".mp4");        } else {            return null;        }        return mediaFile;    }    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {            if (resultCode == RESULT_OK) {                // 捕獲的映像儲存到Intent指定的fileUri                Toast.makeText(this, "Image saved to:\n" + data.getData(),                        Toast.LENGTH_LONG).show();            } else if (resultCode == RESULT_CANCELED) {                // 使用者取消了映像捕獲            } else {                // 映像捕獲失敗,提示使用者            }        }        if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {            if (resultCode == RESULT_OK) {                // 捕獲的視頻儲存到Intent指定的fileUri                Toast.makeText(this, "Video saved to:\n" + data.getData(),                        Toast.LENGTH_LONG).show();            } else if (resultCode == RESULT_CANCELED) {                // 使用者取消了視頻捕獲            } else {                // 視頻捕獲失敗,提示使用者            }        }    }    @Override    protected void onPause() {        super.onPause();        releaseCamera(); // 在暫停事件中馬上釋放網路攝影機    }    private void releaseCamera() {        if (mCamera != null) {            mCamera.release(); // 為其他應用釋放網路攝影機            mCamera = null;        }    }}


Android之TextureView淺析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.