Android TextureView

分享到:

TextureView是Android4.0之后新加入的控件与SurfaceView有些相似,便比后者功能更强大。比如官方称TextureView可以导入视频流或者其它多媒体的内容流(内容流可以是OpenGL渲染的3D影像)。同时也强调TextureView只能在支持硬件加速的界面中使用,而且不需要像TextureView那样新建立一个独立界面才能使用。还支持一些属性调节,比如通过setAlpha方法调节自身的透明度。
网上有人用TextureView代替SurfaceView修改了Android原生相机的取景器界面,找到了这个例子仅供参考:

主界面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代码:

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代码:

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控件
Android基础知识
Android组件
Android实例