博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android之TextureView浅析
阅读量:7067 次
发布时间:2019-06-28

本文共 7470 字,大约阅读时间需要 24 分钟。

近期。在改动Android4.4的原生相机Camera2,非常习惯的去寻找SurfaceView。结果任凭我使用grep还是ack。都无法搜索到SurfaceView,最后还是通过代码CameraActivity-->CameraModule-->PhotoUI-->R.layout.photo_module找到。原来是使用了TextureView。不是非常了解此控件,百度之。在官方API文档中找到此控件:

官方文档大概的意思是:

TextureView能够用来显示内容流。这样一个内容流比如能够视频或者OpenGL的场景。

内容流能够来自本应用程序以及其它进程。

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

与SurfaceView相比,TextureView不会创建一个单独的窗体。这使得它能够像一般的View一样运行一些变换操作,比方移动、动画等等,比如,你能够通过调用myView.setAlpha(0.5f)将TextureView设置成半透明。

使用TextureView非常easy:你须要使用的就是SurfaceTexture,SurfaceTexture能够用于呈现内容。

以下是我写一个小样例来演示怎样渲染相机预览到TextureView,在官方文档样例的基础上略微修改了一下:

main.xml:

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;        }    }}

转载地址:http://ouxll.baihongyu.com/

你可能感兴趣的文章
CentOS7下yum安装Jenkins
查看>>
简练软考知识点整理-确认范围管理
查看>>
不懂这几点就落后了:Android、Python工程师必读!
查看>>
Werkzeug 教程
查看>>
内核参数优化
查看>>
用户,组和权限零碎知识
查看>>
计算机
查看>>
文件修改较优方式
查看>>
oracle导入导出exp,imp
查看>>
oracle check if the display variable is set
查看>>
一键部署Openstack R版
查看>>
《JAVA——帮你解决高并发秒杀》
查看>>
国家级期刊发表要求注意事项
查看>>
C文件操作
查看>>
观察转小写的操作-字符函数
查看>>
Oracle查询访问同一表的两个以上索引(二)
查看>>
office 2016 下载地址
查看>>
Go语言之调试
查看>>
Go语言之 unsafe 包之内存布局
查看>>
Spring Cloud Config 入门
查看>>