Android之TextureView浅析
近期。在改动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浅析的更多相关文章
- Android使用TextureView播放视频
1.引言 如果你想显示一段在线视频或者任意的数据流比如视频或者OpenGL 场景,你可以用android中的TextureView做到. 1).TextureView的兄弟SurfaceView 应用 ...
- Android源码浅析(六)——SecureCRT远程连接Linux,配置端点和字节码
Android源码浅析(六)--SecureCRT远程连接Linux,配置端点和字节码 需要编译源码的同学,一般都是win+虚拟机吧,但是再虚拟机里体验并不是很好,所有市面上有很多的软件能够做到在wi ...
- Android源码浅析(五)——关于定制系统,如何给你的Android应用系统签名
Android源码浅析(五)--关于定制系统,如何给你的Android应用系统签名 今天来点简单的我相信很多定制系统的同学都会有一些特定功能的需求,比如 修改系统时间 静默安装 执行某shell命令 ...
- Android源码浅析(四)——我在Android开发中常用到的adb命令,Linux命令,源码编译命令
Android源码浅析(四)--我在Android开发中常用到的adb命令,Linux命令,源码编译命令 我自己平时开发的时候积累的一些命令,希望对你有所帮助 adb是什么?: adb的全称为Andr ...
- Android源码浅析(三)——Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机
Android源码浅析(三)--Android AOSP 5.1.1源码的同步sync和编译make,搭建Samba服务器进行更便捷的烧录刷机 最近比较忙,而且又要维护自己的博客,视频和公众号,也就没 ...
- Android源码浅析(二)——Ubuntu Root,Git,VMware Tools,安装输入法,主题美化,Dock,安装JDK和配置环境
Android源码浅析(二)--Ubuntu Root,Git,VMware Tools,安装输入法,主题美化,Dock,安装JDK和配置环境 接着上篇,上片主要是介绍了一些安装工具的小知识点Andr ...
- Android源码浅析(一)——VMware Workstation Pro和Ubuntu Kylin 16.04 LTS安装配置
Android源码浅析(一)--VMware Workstation Pro和Ubuntu Kylin 16.04 LTS安装配置 最近地方工作,就是接触源码的东西了,所以好东西还是要分享,系列开了这 ...
- Android 自定义 View 浅析
Android 自定义 View 浅析 概括 说到自定义 View ,就一定得说说 android 系统的UI绘制流程.再说这个流程之前,我们先看一下在每一个 activity 页面中我们的布局 ui ...
- Android应用框架浅析
http://blog.csdn.net/yanbober/article/category/3206943 Android应用层View绘制流程与源码分析 http://blog.csdn.ne ...
随机推荐
- Python 基础 字符串拼接 + if while for循环
注释单行注释 #多行注释 ''' 三个单引号或者三个双引号 """ ''' 用三引号引住可以多行赋值 用户交互 input 字符串拼接 + ""%( ...
- mybaits不能出现小于号
org.xml.sax.SAXParseException; lineNumber: 146; columnNumber: 54; The content of elements must consi ...
- 网页端启动WinForm
网页端启动WinForm 程序 在逛淘宝或者使用QQ相关的产品的时候,比如淘宝我要联系店家点击旺旺图标的时候能够自动启动阿里旺旺进行聊天.之前很奇怪为什么网页端能够自动启动客户端程序,最近在开发吉特仓 ...
- Hdu5517 Triple
Description Given the finite multi-set \(A\) of \(n\) pairs of integers, an another finite multi-set ...
- BZOJ 1854 游戏
Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备,每种装备都有\(2\)个属性,这些属性的值用\([1,10000]\)之间的数表示.当他使用某种装备时,他只能使用该 ...
- linux解压命令
.tar 解包:tar xvf FileName.tar打包:tar cvf FileName.tar DirName(注:tar是打包,不是压缩!)———————————————.gz解压1:gun ...
- 10.在Global全局文件中的Application_BeginRequest示例
只要有人访问本网站,都要执行全局文件的Application_BeginRequest事件.因此我们可以防盗链. 示例要求:凡不是网站本机登录的都给客户端提示,用图片显示. 分析:由于网页在加载时不是 ...
- Spark MLBase分布式机器学习系统入门:以MLlib实现Kmeans聚类算法
1.什么是MLBaseMLBase是Spark生态圈的一部分,专注于机器学习,包含三个组件:MLlib.MLI.ML Optimizer. ML Optimizer: This layer aims ...
- 14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率:
14.6.8 Configuring the InnoDB Master Thread IO Rate 配置InnoDB 主线程IO 速率: 主线程 在InnoDB 是一个线程 执行各种任务在后台. ...
- 创建range分区
drop table T_PM_ACCT_DTL_AF_TEST; create table T_PM_ACCT_DTL_AF_TEST ( DATA_DATE date, AC ...