Android 调用摄像头功能【拍照与视频】
版权声明:本文为博主原创文章,未经博主同意不得转载。 https://blog.csdn.net/ma_hoking/article/details/28292973
应用场景:
在Android开发过程中,有时须要调用手机自身设备的功能,上篇文章主要側重摄像头拍照功能的调用。本篇文章将综合实现拍照与视频的操作。
知识点介绍:
该部分请阅读 【Android 调用摄像头功能】
使用方式:
第一步:
新建一个Android项目CameraPhotoVedio,包括两个Activity: MainActivity、CameraActivity。
第二步:
【activity_main.xml】
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/shape_main"
tools:context=".MainActivity" >
<LinearLayout android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_width="match_parent"
android:orientation="vertical">
<ImageView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_gravity="center"
android:src="@drawable/main"/>
</LinearLayout>
<LinearLayout android:layout_height="wrap_content"
android:layout_marginTop="100dp"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<Button
android:id="@+id/main_button"
android:layout_height="50dp"
android:layout_marginBottom="50dp"
android:background="@drawable/shape_main"
android:layout_width="match_parent"
android:textColor="#FFFFFF"
android:text="使用摄像头"/>
</LinearLayout>
</RelativeLayout>
【MainActivity.java】
import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class MainActivity extends Activity {
private Button button; //调用摄像头按钮
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initViews();
}
private void initViews() {
button = (Button) findViewById(R.id.main_button);
button.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(getApplicationContext(), CameraActivity.class));
}
});
}
}
【activity_camera.xml】
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:background="#FFFFFF"
android:layout_height="match_parent"
tools:context=".CameraActivity" >
<SurfaceView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/camera_surfaceview"/>
<TextView android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="计时区域"
android:id="@+id/camera_time"/>
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<Button android:layout_height="30dp"
android:layout_width="match_parent"
android:layout_marginBottom="20dp"
android:layout_weight="1"
android:background="@drawable/shape_main"
android:id="@+id/camera_photo"
android:layout_marginLeft="5dp"
android:textColor="#FFFFFF"
android:layout_marginRight="5dp"
android:text="照片摄取"/>
<Button android:layout_height="30dp"
android:layout_marginBottom="20dp"
android:layout_width="match_parent"
android:layout_weight="1"
android:background="@drawable/shape_main"
android:id="@+id/camera_vedio"
android:layout_marginLeft="5dp"
android:textColor="#FFFFFF"
android:layout_marginRight="5dp"
android:text="视频摄取"/>
</LinearLayout>
</RelativeLayout>
【CameraActivity.java】
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
import com.example.cameraphotovideo.utils.FormatUtil;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.app.Activity;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class CameraActivity extends Activity {
private String tag ="MaHaochen_______CameraActivity";
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private Camera camera;
private MediaRecorder mediaRecorder;
private Button photoButton; //拍照按钮
private Button vedioButton; //摄像按钮
private TextView timeTextView;
protected boolean isPreview = false; //摄像区域是否准备良好
private boolean isRecording = true; // true表示没有录像,点击開始。false表示正在录像,点击暂停
private boolean bool;
private int hour = 0;
private int minute = 0; //计时专用
private int second = 0;
private File mRecVedioPath;
private File mRecAudioFile;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
initCamera();
initViews();
}
//初始化摄像头
private void initCamera() {
mRecVedioPath = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/mahc/video/temp/");
if (!mRecVedioPath.exists()) {
mRecVedioPath.mkdirs();
}
surfaceView = (SurfaceView) findViewById(R.id.camera_surfaceview);
SurfaceHolder cameraSurfaceHolder = surfaceView.getHolder();
cameraSurfaceHolder.addCallback(new Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();
//设置Camera的角度/方向
camera.setDisplayOrientation(90);
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewFrameRate(5); // 每秒5帧
parameters.setPictureFormat(ImageFormat.JPEG);// 设置照片的输出格式
parameters.set("jpeg-quality", 85);// 照片质量
camera.setParameters(parameters);
camera.setPreviewDisplay(holder);
isPreview = true;
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
surfaceHolder = holder;
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
surfaceHolder = holder;
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
if (isPreview) {
camera.stopPreview();
isPreview = false;
}
camera.release();
camera = null; // 记得释放Camera
}
surfaceView = null;
surfaceHolder = null;
mediaRecorder = null;
}
});
//开发时建议设置
//This method was deprecated in API level 11. this is ignored, this value is set automatically when needed.
cameraSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
//初始化视图组件
private void initViews() {
timeTextView = (TextView) findViewById(R.id.camera_time);
timeTextView.setVisibility(View.GONE);
photoButton = (Button) findViewById(R.id.camera_photo);
vedioButton = (Button) findViewById(R.id.camera_vedio);
ButtonOnClickListener onClickListener = new ButtonOnClickListener();
photoButton.setOnClickListener(onClickListener);
vedioButton.setOnClickListener(onClickListener);
}
class ButtonOnClickListener implements OnClickListener{
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.camera_vedio:
//点击開始录像
if(isRecording){
if (isPreview) {
camera.stopPreview();
camera.release();
camera = null;
}
second = 0;
minute = 0;
hour = 0;
bool = true;
if(null==mediaRecorder){
mediaRecorder = new MediaRecorder();
}else {
mediaRecorder.reset();
}
//表面设置显示记录媒体(视频)的预览
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
//開始捕捉和编码数据到setOutputFile(指定的文件)
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//设置用于录制的音源
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
//设置在录制过程中产生的输出文件的格式
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
//设置视频编码器,用于录制
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
//设置audio的编码格式
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
//设置要捕获的视频的宽度和高度
mediaRecorder.setVideoSize(320, 240);
// 设置要捕获的视频帧速率
mediaRecorder.setVideoFrameRate(15);
try {
mRecAudioFile = File.createTempFile("Vedio", ".3gp",
mRecVedioPath);
} catch (IOException e) {
e.printStackTrace();
}
mediaRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());
try {
mediaRecorder.prepare();
timeTextView.setVisibility(View.VISIBLE);
handler.postDelayed(task, 1000);
mediaRecorder.start();
} catch (Exception e) {
e.printStackTrace();
}
isRecording = !isRecording;
Log.e(tag, "=====開始录制视频=====");
}else {
//点击停止录像
bool = false;
mediaRecorder.stop();
timeTextView.setText(FormatUtil.format(hour)+":"+FormatUtil.format(minute)+":"+ FormatUtil.format(second));
mediaRecorder.release();
mediaRecorder = null;
FormatUtil.videoRename(mRecAudioFile);
Log.e(tag, "=====录制完毕,已保存=====");
isRecording = !isRecording;
try {
camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
// parameters.setPreviewFrameRate(5); // 每秒5帧
parameters.setPictureFormat(ImageFormat.JPEG);// 设置照片的输出格式
parameters.set("jpeg-quality", 85);// 照片质量
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
isPreview = true;
} catch (Exception e) {
e.printStackTrace();
}
}
break;
case R.id.camera_photo:
if (mediaRecorder != null) {
try {
bool = false;
mediaRecorder.stop();
timeTextView.setText(FormatUtil.format(hour) + ":" + FormatUtil.format(minute) + ":"
+ FormatUtil.format(second));
mediaRecorder.release();
mediaRecorder = null;
FormatUtil.videoRename(mRecAudioFile);
} catch (Exception e) {
e.printStackTrace();
}
isRecording = !isRecording;
Log.e(tag, "=====录制完毕,已保存=====");
try {
camera = Camera.open();
Camera.Parameters parameters = camera.getParameters();
// parameters.setPreviewFrameRate(5); // 每秒5帧
parameters.setPictureFormat(ImageFormat.JPEG);// 设置照片的输出格式
parameters.set("jpeg-quality", 85);// 照片质量
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
isPreview = true;
} catch (Exception e) {
e.printStackTrace();
}
}
if (camera != null) {
camera.autoFocus(null);
camera.takePicture(null, null, new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
new SavePictureTask().execute(data);
camera.startPreview();
Log.e(tag,"=====拍照成功=====");
}
}); // 拍照
}
break;
default:
break;
}
}
}
/*
* 定时器设置,实现计时
*/
private Handler handler = new Handler();
private Runnable task = new Runnable() {
public void run() {
if (bool) {
handler.postDelayed(this, 1000);
second++;
if (second >= 60) {
minute++;
second = second % 60;
}
if (minute >= 60) {
hour++;
minute = minute % 60;
}
timeTextView.setText(FormatUtil.format(hour) + ":" + FormatUtil.format(minute) + ":"
+ FormatUtil.format(second));
}
}
};
class SavePictureTask extends AsyncTask<byte[], String, String> {
@Override
protected String doInBackground(byte[]... params) {
String path = Environment.getExternalStorageDirectory()
.getAbsolutePath() + "/mahc/image";
File out = new File(path);
if (!out.exists()) {
out.mkdirs();
}
File picture = new File(path+"/"+new Date().getTime()+".jpg");
try {
FileOutputStream fos = new FileOutputStream(picture.getPath());
fos.write(params[0]);
fos.close();
} catch (Exception e) {
e.printStackTrace();
}
Log.e(tag, "=====照片保存完毕=====");
CameraActivity.this.finish();
return null;
}
}
}
第三步:该项目须要一个工具类FormatUtil.java
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.os.Environment;
public class FormatUtil {
/**
* 将缓存目录的数据转存到vedio文件下
* @param recAudioFile
*/
public static void videoRename(File recAudioFile) {
String path = Environment.getExternalStorageDirectory()
.getAbsolutePath()+ "/mahc/video/"+ "0" + "/";
String fileName = new SimpleDateFormat("yyyyMMddHHmmss")
.format(new Date()) + ".3gp";
File out = new File(path);
if (!out.exists()) {
out.mkdirs();
}
out = new File(path, fileName);
if (recAudioFile.exists())
recAudioFile.renameTo(out);
}
/**
* 用以计时操作的相关方法
* @param num
* @return
*/
public static String format(int num){
String s = num + "";
if (s.length() == 1) {
s = "0" + s;
}
return s;
}
}
第四步:本项目须要处理界面的背景样式和按钮的背景,所以须要在res/drawable文件新建shape_main.xml。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<gradient
android:startColor="#FFCC99"
android:endColor="#99CC66"
android:centerColor="#0066CC"
android:angle="45" />
</shape>
页面效果:
效果截图
下载地址:
Android 调用摄像头功能【拍照与视频】的更多相关文章
- html5调用摄像头实现拍照
技术时刻都在前进着.我们的需求也是时刻在改变着.最近在开发中遇到了用户进行账号注册时需要个人图像,网站提供自动拍照功能.还有在登录了PC之后,手机端进行登录时只需要扫描一下PC上的二维码就可以登录.这 ...
- HTML之调用摄像头实现拍照和摄像功能
应该有很多人知道,我们的手机里面有个功能是“抓拍入侵者”,说白了就是在解锁应用时如果我们输错了密码手机就会调用这一功能实现自动拍照. 其实在手机上还有很多我们常用的软件都有类似于这样的功能,比如微信扫 ...
- android: 调用摄像头拍照
很多应用程序都可能会使用到调用摄像头拍照的功能,比如说程序里需要上传一张图片 作为用户的头像,这时打开摄像头拍张照是最简单快捷的.下面就让我们通过一个例子来学 习一下,如何才能在应用程序里调用手机的摄 ...
- android ——调用摄像头拍照和相册
先在布局文件中加入两个按钮和一个图片控件 <?xml version="1.0" encoding="utf-8"?> <LinearLayo ...
- Android调用相机实现拍照并裁剪图片,调用手机中的相冊图片并裁剪图片
在 Android应用中,非常多时候我们须要实现上传图片,或者直接调用手机上的拍照功能拍照处理然后直接显示并上传功能,以下将讲述调用相机拍照处理图片然后显示和调用手机相冊中的图片处理然后显示的功能,要 ...
- html5调用摄像头并拍照
随着flash被禁用,flash上传附件的方式已成为过去,现在开始用html5上传了.本片文章就是介绍如何使用html5拍照,其实挺简单的原理: 调用摄像头采集视频流,利用canvas的特性生成bas ...
- Android 调用系统照相机拍照和录像
本文实现android系统照相机的调用来拍照 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.a ...
- Android 调用系统相机拍照保存以及调用系统相册的方法
系统已经有的东西,如果我们没有新的需求的话,直接调用是最直接的.下面讲讲调用系统相机拍照并保存图片和如何调用系统相册的方法. 首先看看调用系统相机的核心方法: Intent camera = new ...
- java javacv调用摄像头并拍照
调用摄像头并拍张照片,我一开始用的java的jmf媒体框架,但这个有很多的局限性不好使并且很有麻烦,兜了一圈发现javacv东西,研究之后这东西简单,方便:废话不多说了来重点. javacv官网:点击 ...
随机推荐
- Python web框架 Tornado异步非阻塞
Python web框架 Tornado异步非阻塞 异步非阻塞 阻塞式:(适用于所有框架,Django,Flask,Tornado,Bottle) 一个请求到来未处理完成,后续一直等待 解决方案: ...
- JS框架_(coolShow.js)图片旋转动画特效
百度云盘 传送门 密码:ble6 coolShow.js插件图片旋转动画效果 <!DOCTYPE HTML> <head> <meta http-equiv=" ...
- 前端学习之三——jquery选择器
Jquery中的选择器分为几大类:基本过滤选择器,层次选择器,内容过滤选择器,可见性过滤选择器,属性过滤选择器,子元素过滤选择器,表单对象选择器和表单对象属相过滤选择器. 1.非基本过滤选择器,一般需 ...
- MQTT协议 Websocket JS客户端
特别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/ ...
- 验证TXT解析的正确性
需要用到TXT解析,不同于CNAME和A解析,可以用PING命令验证,要验证TXT解析需要用到如下命令 nslookup -q=TXT txtdemo.lei.cool 8.8.8.8 输出内容如下 ...
- Java-线程等待、唤醒与中断
一.sleep() 与 wait() 两者都会让当前线程进入等待状态.唤醒后都需要等待 CPU 资源,不一定会立即执行.若在等待期间被调用此线程的的 interrupt() 方法,将会产生 Inter ...
- opensatck误删除service项目
由于在清除资源时,未考虑到租户service,将其一并删除,于是有了下面的填坑之旅 1,需要找到删除的services-id,查看keytone的log, grep -r "DELETE&q ...
- Python_List对象内置方法详解
目录 目录 前言 软件环境 列表List 修改列表的元素 插入列表元素 extend 将序列中的元素迭代的附加到list中 insert 在指定的索引号中插入一个元素 删除列表元素 del 删除Lis ...
- 阶段3 2.Spring_03.Spring的 IOC 和 DI_3 spring基于XML的IOC环境搭建和入门
创建新项目 修改为jar包的方式 把上一个工程内的代码 java下的com复制过来 由于配置文件没有,所以一运行就会报错 factory文件夹整个删除 dao的实现类 这里删除 测试类保留这两行代码 ...
- Centos7 安装可视化界面
yum group list Output: Loaded plugins: fastestmirror There is no installed groups file. Maybe run: y ...