Android实现调用摄像头拍照与视频功能

应用场景:

在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实现调用摄像头拍照与视频功能

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

您可能感兴趣的文章:

  • Android 实现调用系统照相机拍照和录像的功能
  • Android 调用系统照相机拍照和录像
  • Android自定义照相机倒计时拍照
  • Android调用系统摄像头拍照并显示在ImageView上
  • Android实现摄像头拍照功能
  • Android调用摄像头拍照开发教程
  • Android实现调用摄像头进行拍照功能
  • Android实现拍照、选择图片并裁剪图片功能
  • Android调用系统照相机拍照与摄像的方法
(0)

相关推荐

  • Android调用摄像头拍照开发教程

    现在很多应用中都会要求用户上传一张图片来作为头像,首先我在这接收使用相机拍照和在相册中选择图片.接下来先上效果图: 接下来看代码: 1.布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schem

  • Android调用系统摄像头拍照并显示在ImageView上

    简介 现在市面上的apk只要涉及用户中心都会有头像,而且这个头像也是可自定义的,有的会采取读取相册选择其中一张作为需求照片,另一种就是调用系统摄像头拍照并获取即时照片,本博文就是讲述如何调用摄像头拍照并显示在指定的控件上. 先来看看效果图 由于这里我用的是模拟器没有摄像头,所以拍照是黑的,至于里面2个红色圆圈那是Genymotion自带的标志. 实现起来比较简单: activity_main.xml <?xml version="1.0" encoding="utf-8

  • Android实现拍照、选择图片并裁剪图片功能

    一. 实现拍照.选择图片并裁剪图片效果 按照之前博客的风格,首先看下实现效果. 二. uCrop项目应用 想起之前看到的Yalantis/uCrop效果比较绚,但是研究源码之后发现在定制界面方面还是有一点的限制,于是在它的基础上做了修改Android-Crop,把定制界面独立出来,让用户去自由设置.下图为使用Android-Crop实现的模仿微信选择图片并裁剪Demo. 三. 实现思路 比较简单的选择设备图片裁剪,并将裁剪后的图片保存到指定路径: 调用系统拍照,将拍照图片保存在SD卡,然后裁剪图

  • Android调用系统照相机拍照与摄像的方法

    前言 在很多场景中,都需要用到摄像头去拍摄照片或视频,在照片或视频的基础之上进行处理.但是Android系统源码是开源的,很多设备厂商均可使用,并且定制比较混乱.一般而言,在需要用到摄像头拍照或摄像的时候,均会直接调用系统现有的相机应用,去进行拍照或摄像,我们只取它拍摄的结果进行处理,这样避免了不同设备的摄像头的一些细节问题.本篇博客将介绍在Android应用中,如何调用系统现有的相机应用去拍摄照片与短片,并对其进行处理,最后均会以一个简单的Demo来演示效果. 1.系统现有相机应用的调用 对于

  • Android 实现调用系统照相机拍照和录像的功能

    本文实现android系统照相机的调用来拍照 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_heig

  • Android实现调用摄像头进行拍照功能

    现在Android智能手机的像素都会提供照相的功能,大部分的手机的摄像头的像素都在1000万以上的像素,有的甚至会更高.它们大多都会支持光学变焦.曝光以及快门等等. 下面的程序Demo实例示范了使用Camera v2来进行拍照,当用户按下拍照键时,该应用会自动对焦,当对焦成功时拍下照片. layout/activity_main.xml界面布局代码如下: <?xml version="1.0" encoding="utf-8"?> <manifes

  • Android 调用系统照相机拍照和录像

    本文实现android系统照相机的调用来拍照 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_heig

  • Android自定义照相机倒计时拍照

    自定义拍照会用到SurfaceView控件显示照片的预览区域,以下是布局文件: 两个TextView是用来显示提示信息和倒计时的秒数的 相关教程:Android开发从相机或相册获取图片裁剪 Android启动相机拍照并返回图片 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools&qu

  • Android实现摄像头拍照功能

    应用场景: 在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用. 知识点介绍: 使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature. <!--摄像头权限 --> <uses-permission android:name="android.permission.CAMERA" /> <!--存储权限 SD卡读写权限

  • Android实现调用摄像头拍照与视频功能

    应用场景: 在Android开发过程中,有时需要调用手机自身设备的功能,上篇文章主要侧重摄像头拍照功能的调用.本篇文章将综合实现拍照与视频的操作. 知识点介绍: 该部分请阅读 [Android 调用摄像头功能] 使用方式: 第一步: 新建一个Android项目CameraPhotoVedio,包含两个Activity: MainActivity.CameraActivity. 第二步: activity_main.xml <RelativeLayout xmlns:android="htt

  • Android实现调用摄像头拍照并存储照片

    目录 1.前期准备 2.主要方法 1.需要使用Intent调用摄像头 2.需要检查SD卡(外部存储)状态 3.获取图片及其压缩图片 3.案例展示 1.Layout 2.MainActivity 1.前期准备 需要在Manifest中添加相关权限 <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.ca

  • Android实现调用摄像头和相册的方法

    Android调用摄像头是很方便的.先看一下界面 布局文件activity_main.xml源码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:l

  • Python OpenCV 调用摄像头并截图保存功能的实现代码

    0x01 OpenCV安装 通过命令pip install opencv-python 安装 pip install opencv-python 0x02  示例 import cv2 cap = cv2.VideoCapture(0) #打开摄像头 while(1): # get a frame ret, frame = cap.read() # show a frame cv2.imshow("capture", frame) #生成摄像头窗口 if cv2.waitKey(1)

  • VS2017+Qt5+Opencv3.4调用摄像头拍照并存储

    1. Qt的ui界面,找着画就好 2.头文件直接贴出,之后有时间慢慢解释吧 #pragma once #include <QtWidgets/QWidget> #include "ui_camaraGet.h" #ifndef CAMARAGET_H #define CAMARAGET_H #include <opencv2\core\core.hpp> #include <QWidget> #include <QImage> #incl

  • Androidstudio调用摄像头拍照并保存照片

    本文实例为大家分享了Androidstudio调用摄像头拍照并保存照片的具体代码,供大家参考,具体内容如下 首先在manifest.xmlns文件中声明权限 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package="com.example

  • C#使用Aforge调用摄像头拍照的方法

    本文实例为大家分享了C#使用Aforge调用摄像头拍照的具体代码,供大家参考,具体内容如下 一.新建一个Winform项目 二.使用Nuget添加引用 安装下图中红色框住的两个程序包 安装完后发现安装了如下图的程序包,这是因为上述两个程序包存在对其它程序包的依赖. 三.编写程序 1.窗体设计,摄像头是下拉列表(cmbCamera,控件命名,下同),虽然示例只用到一个摄像头,但是该Demo可用于多个摄像头间切换场景,分辨率是下拉列表(cmbResolution),列出摄像头所支持的分辨率,一个Vi

  • Android实现调用摄像头

    应用场景: 在Android开发过程中,有时需要调用手机自身设备的功能,本文侧重摄像头拍照功能的调用. 知识点介绍: 使用权限:调用手机自身设备功能(摄像头拍照功能),应该确保已经在AndroidManifest.xml中正确声明了对摄像头的使用及其它相关的feature 1. 摄像头相关权限设置 <!--摄像头权限 --> <uses-permission android:name="android.permission.CAMERA" /> <!--存

随机推荐