1.效果图,功能没有录制出来。

基本实现了拍照,录制视频,前后摄像头切换的功能,可以转屏,聚焦。

代码在最下面,可以看代码,运行apk看实际效果。

2.权限不能忘

   <uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>

  

3.工具类

package com.example.mycamera;

import android.content.Context;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List; import static android.content.ContentValues.TAG; /**
* Created by guoxw on 2017/10/31.
* <!- 实现拍照,录像: 并保存图片,视频到本地></!->
*/ public class CameraUtils { private MediaRecorder mediaRecorder;
private Camera camera;
/*** 标识当前是前摄像头还是后摄像头 back:0 front:1*/
private int backOrFtont = 0;
private SurfaceHolder.Callback callback;
private Context context;
private SurfaceView surfaceView;
/***录制视频的videoSize*/
private int height, width;
/***photo的height ,width*/
private int heightPhoto, widthPhoto; public void create(SurfaceView surfaceView, Context context) {
this.context = context;
this.surfaceView = surfaceView;
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceView.setKeepScreenOn(true);
callback = new SurfaceHolder.Callback() {
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
getVideoSize();
mediaRecorder = new MediaRecorder(); } public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
doChange(holder);
focus();
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (camera != null) {
camera.release();
camera = null;
}
}
};
surfaceView.getHolder().addCallback(callback); } private void doChange(SurfaceHolder holder) {
try {
camera.setPreviewDisplay(holder);
camera.setDisplayOrientation(90);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 切换摄像头
*/
public void changeCamera() {
int cameraCount = 0;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT && backOrFtont == 0) {
camera.stopPreview();
camera.release();
camera = null;
camera = Camera.open(i);
try {
camera.setPreviewDisplay(surfaceView.getHolder());
camera.setDisplayOrientation(90);
} catch (IOException e) {
e.printStackTrace();
}
backOrFtont = 1;
camera.startPreview();
break;
} else if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK && backOrFtont == 1) {
camera.stopPreview();
camera.release();
camera = null;
camera = Camera.open(i);
try {
camera.setPreviewDisplay(surfaceView.getHolder());
camera.setDisplayOrientation(90);
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
backOrFtont = 0;
break;
}
} } public void stopRecord() {
mediaRecorder.release();
camera.release();
mediaRecorder = null;
camera = Camera.open();
mediaRecorder = new MediaRecorder();
doChange(surfaceView.getHolder());
} public void stop() {
if (mediaRecorder != null && camera != null) {
mediaRecorder.release();
camera.release();
}
} public void destroy() {
if (mediaRecorder != null && camera != null) {
mediaRecorder.release();
camera.release();
mediaRecorder = null;
camera = null;
} } /**
* @param path 保存的路径
* @param name 录像视频名称(不包含后缀)
*/
public void startRecord(String path, String name) {
camera.unlock();
mediaRecorder.setCamera(camera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
//mediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_LOW));
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setVideoEncodingBitRate(700 * 1024);
mediaRecorder.setVideoSize(width, height);
mediaRecorder.setVideoFrameRate(24);
//getVideoSize();
File file = new File(path);
if (!file.exists()) {
file.mkdirs();
}
mediaRecorder.setOutputFile(path + File.separator + name + ".mp4");
File file1 = new File(path + File.separator + name + ".mp4");
if (file1.exists()) {
file1.delete();
}
mediaRecorder.setPreviewDisplay(surfaceView.getHolder().getSurface());
/***不设置时,录制的视频总是倒着,翻屏导致视频上下翻滚*/
mediaRecorder.setOrientationHint(0);
try {
mediaRecorder.prepare();
mediaRecorder.start();
} catch (IOException e) {
e.printStackTrace();
}
} /***
* 获取SupportedVideoSizes 控制输出视频width在300到600之间(尽可能小)
* 获取PictureSize的大小(控制在w:1000-2000之间)
*/
public void getVideoSize() {
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> videoSize = parameters.getSupportedVideoSizes();
for (int i = 0; i < videoSize.size(); i++) {
int width1 = videoSize.get(i).width;
int height1 = videoSize.get(i).height;
if (width1 >= 300 && width1 <= 600) {
if (height1 >= 200 && height1 <= 600) {
width = width1;
height = height1;
} }
Log.d(TAG, "getVideoSize:----w:-- " + videoSize.get(i).width + "---h:--" + videoSize.get(i).height);
}
List<Camera.Size> photoSize = parameters.getSupportedPictureSizes();
for (int i = 0; i < photoSize.size(); i++) {
int width1 = photoSize.get(i).width;
int height1 = photoSize.get(i).height;
if (width1 >= 1000 && width1 <= 2000) {
if (height1 >= 600 && height1 <=2000) {
widthPhoto = width1;
heightPhoto = height1;
} }
} } public void takePicture(String photoPath, String photoName) { camera.takePicture(null, null, new PictureCallBack(photoPath, photoName));
} /**
* 聚焦
*/
public void focus(){
Camera.Parameters parameters=camera.getParameters();
parameters.setPictureSize(widthPhoto,heightPhoto);
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
camera.setParameters(parameters);
camera.cancelAutoFocus();
} /*** 拍照功能*/
private class PictureCallBack implements Camera.PictureCallback {
/*** 照片保存的路径和名称*/
private String path;
private String name; public PictureCallBack(String path, String name) {
this.path = path;
this.name = name;
} @Override
public void onPictureTaken(byte[] bytes, Camera camera) {
File file1 = new File(path);
if (!file1.exists()) {
file1.mkdirs();
}
File file = new File(path, name);
if (file.exists()) {
file.delete();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
try {
fos.write(bytes);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
camera.startPreview();
}
}
}

  

3.使用就直接调用方法了。

package com.example.mycamera;

import android.os.Bundle;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.ImageView; public class MainActivity extends AppCompatActivity { private static final String TAG = "PlayActivity";
private SurfaceView surfaceView;
private CameraUtils cameraUtils;
private String path, name;
private ImageView btn;
private ImageView camera;
private ImageView change;
int x = 0; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: ");
getSupportActionBar().hide(); btn = (ImageView) findViewById(R.id.btn);
camera = (ImageView) findViewById(R.id.camera);
change = (ImageView) findViewById(R.id.change);
surfaceView = (SurfaceView) findViewById(R.id.surfaceView); cameraUtils = new CameraUtils();
cameraUtils.create(surfaceView, this);
path = Environment.getExternalStorageDirectory().getAbsolutePath();
name = "Video"; btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (x == 0) {
// cameraUtils.changeCamera();
cameraUtils.startRecord(path, name);
btn.setImageResource(R.drawable.video);
x = 1;
} else if (x == 1) {
cameraUtils.stopRecord();
btn.setImageResource(R.drawable.video1);
x=0;
} }
});
camera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
cameraUtils.takePicture(path, "name.png"); }
}); change.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
cameraUtils.changeCamera();
}
}); } @Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume: ");
} @Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause: ");
} @Override
protected void onStop() {
super.onStop();
Log.d(TAG, "onStop: ");
cameraUtils.stop();
} @Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: ");
cameraUtils.destroy();
}
}

  

code:

https://pan.baidu.com/s/1hr7KnA0

Android拍照,录制视频,相机简单功能实现的更多相关文章

  1. 使用Android编写录制视频小程序演示样例

    主要实现录制功能的类:Camera类和MediaRecorder类.功能描写叙述:首先进入视频录制界面,点击录像button进入录像功能界面,点击录制開始录制视频, 点击停止button,将录制的视频 ...

  2. Android adb录制视频和截屏的dos脚本

    以下是本人写的脚本,用于录制android手机视频.截屏 dos脚本文件名:screenrecord.bat @ECHO OFF CLS color 0a set SCREEN_RECORD_SAVE ...

  3. Android手机录制视频 实时传输(转载)

    最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...

  4. iOS开发系列--音频播放、录音、视频播放、拍照、视频录制

    --iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...

  5. iOS开发----音频播放、录音、视频播放、拍照、视频录制

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  6. 音频播放、录音、视频播放、拍照、视频录制-b

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  7. iOS音频播放、录音、视频播放、拍照、视频录制

    随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...

  8. Delphi - 利用DLL编程控制摄像头实现拍照、录制视频

    Delphi利用avicap32.dll编程控制摄像头实现拍照.录制视频 项目需求:平板电脑(Windows系统)一维/二维码扫描功能: 需求分析: 需要扫描一维/二维码时,分两步实现. 第一步,av ...

  9. android 拍照上传文件 原生定位

    最近公司需要一个android拍照上传和定位功能的的单一功能页面,一开始选择ionic cordova angular的一套H5框架,但是遇到和上传文件报错的问题,bug找了一天没找到原因,怀疑是io ...

随机推荐

  1. 彻底弄清楚session是什么?

    搬运自博主xueqinna的CSDN博客,根据自己的理解修改了部分内容,介意者请前往原博主博客看原文. 今天就来彻底的学一下session是个啥,作者罗列了几个要点:1.session 是啥?2.怎么 ...

  2. Codeforces 902B - Coloring a Tree

    传送门:http://codeforces.com/contest/902/problem/B 本题是一个关于“树”的问题. 有一棵n个结点的有根树,结点按照1~n编号,根结点为1.cv为结点v的色号 ...

  3. 11、mybatis的映射xml中参数类型的别名

    在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型.需要resultType指定输出结果的映射类型. 如果在指定类型时输入类型全 ...

  4. 在Win32 Application 环境下实现MFC窗口的创建

    // Win32下MFC.cpp : Defines the entry point for the application.// #include "stdafx.h" clas ...

  5. SCU - 4110 - PE class

    先上题目: 4110: PE class Submit your solution     Discuss this problem     Best solutions   Description ...

  6. ExtJs之Ext.comboBox的远程数据源读取程序

    既然可以测试本地AJAX,那就把书前面的代码作一次学习吧. <!DOCTYPE html> <html> <head> <title>ExtJs< ...

  7. spring mvc中的@propertysource

    在spring mvc中,在配置文件中的东西,可以在java代码中通过注解进行读取了: @PropertySource  在spring 3.1中开始引入 比如有配置文件 config.propert ...

  8. java SE与java EE , java ME之间的关系

    question: Which one should I install when I want to start learning Java? I'm going to start with som ...

  9. pl/sql developer 布局结构保存

    pl/sql developer 布局结构保存 调整了工具栏,调整了窗体框位置,点击 窗口->保存版面 就可以保留当前的调整的结果,不用一次一次调整了: 也可以在工具 -> 首选项 -&g ...

  10. java 线程 错失的信号、notify() 与notifyAll的使用

    package org.rui.thread.block; import java.util.Timer; import java.util.TimerTask; import java.util.c ...