Android拍照,录制视频,相机简单功能实现
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拍照,录制视频,相机简单功能实现的更多相关文章
- 使用Android编写录制视频小程序演示样例
主要实现录制功能的类:Camera类和MediaRecorder类.功能描写叙述:首先进入视频录制界面,点击录像button进入录像功能界面,点击录制開始录制视频, 点击停止button,将录制的视频 ...
- Android adb录制视频和截屏的dos脚本
以下是本人写的脚本,用于录制android手机视频.截屏 dos脚本文件名:screenrecord.bat @ECHO OFF CLS color 0a set SCREEN_RECORD_SAVE ...
- Android手机录制视频 实时传输(转载)
最近调研android视频录制.另一部手机实时观看,大致有以下几种思路. 1. android手机充当服务器,使用NanoHTTPD充当服务器,另一部手机或者pc通过输入http://手机的ip:80 ...
- iOS开发系列--音频播放、录音、视频播放、拍照、视频录制
--iOS多媒体 概览 随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制, ...
- iOS开发----音频播放、录音、视频播放、拍照、视频录制
随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...
- 音频播放、录音、视频播放、拍照、视频录制-b
随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...
- iOS音频播放、录音、视频播放、拍照、视频录制
随着移动互联网的发展,如今的手机早已不是打电话.发短信那么简单了,播放音乐.视频.录音.拍照等都是很常用的功能.在iOS中对于多媒体的支持是非常强大的,无论是音视频播放.录制,还是对麦克风.摄像头的操 ...
- Delphi - 利用DLL编程控制摄像头实现拍照、录制视频
Delphi利用avicap32.dll编程控制摄像头实现拍照.录制视频 项目需求:平板电脑(Windows系统)一维/二维码扫描功能: 需求分析: 需要扫描一维/二维码时,分两步实现. 第一步,av ...
- android 拍照上传文件 原生定位
最近公司需要一个android拍照上传和定位功能的的单一功能页面,一开始选择ionic cordova angular的一套H5框架,但是遇到和上传文件报错的问题,bug找了一天没找到原因,怀疑是io ...
随机推荐
- jQuery实现菜单全选/不选
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 团体程序设计天梯赛-练习集-L1-036. A乘以B
L1-036. A乘以B 看我没骗你吧 —— 这是一道你可以在10秒内完成的题:给定两个绝对值不超过100的整数A和B,输出A乘以B的值. 输入格式: 输入在第一行给出两个整数A和B(-100 < ...
- 【转载】Jsp页面传Json数据到服务端,转对象或集合进行数据处理
需求:1.将页面数据带到服务端并转成对象,2.将页面的集合数据带到服务端转List实现:用ajax请求传递数据,数据格式为json JS方法: testJsonMethod = function(){ ...
- 洛谷P1996 约瑟夫问题【队列】
题目背景 约瑟夫是一个无聊的人!!! 题目描述 n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,--依次类推,直到所有的人都出 ...
- [luogu4161 SCOI2009]游戏 (DP)
传送门 Solution 可以发现实际上是把n分为几个循环节,然后找循环节的\(lcm\)是这次的排数 而\(lcm\)必然是一些最高次幂的质数的成积,那么就dp求一下所有情况就好了 PS:注意并不是 ...
- Tensorflow 0.8.0 安装配置方法
本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/51280087 折腾了一下,给工作站配置 ...
- netty心跳机制和断线重连(四)
心跳是为了保证客户端和服务端的通信可用.因为各种原因客户端和服务端不能及时响应和接收信息.比如网络断开,停电 或者是客户端/服务端 高负载. 所以每隔一段时间 客户端发送心跳包到客户端 服务端做出心 ...
- 2015多校联合训练第一场Tricks Device(hdu5294)
题意:给一个无向图,给起点s,终点t,求最少拆掉几条边使得s到不了t,最多拆几条边使得s能到t 思路: 先跑一边最短路,记录最短路中最短的边数.总边数-最短边数就是第二个答案 第一个答案就是在最短路里 ...
- LeetCode之RemoveElement
题目: Given an array and a value, remove all instances of that value in place and return the new lengt ...
- Data Binding Guide——google官方文档翻译(下)
这篇博客是Data Binding Guide官网文档翻译的下篇.假设没看过前半部分翻译的能够先看Data Binding Guide--google官方文档翻译(上) 一,数据对象 不论什么不含业 ...