Android最新相机(Camera)拍照、拍视频全面总结
- 介绍
- 利用系统相机
- 调用系统相机拍照
- 获取小图标
- 获取全尺寸图片
- 添加到相册
- 系统相机拍视频
- 调用系统相机拍照
- 自定义相机
- 自定义相机拍照
- 监测设备是否有相机可使用
- 利用SurfaceView创建拍照时预览界面
- 拍照并且在回调方法中保存文件
- 最后释放相机资源
- 自定义相机拍照
介绍
拍照或者拍视频应该是大多数APP都需要去实现的功能,可以说这是既常用又容易出错的地方。比如在Android 6.0之后需要动态申请权限,Android 7.0之后将文件路径由file://修改为content://等等。特别是Android自身对相机都设计了两套API,android.hardware.Camera和android.hardware.camera2,由此可见需要对相机功能做一个总结,两篇文章分别用android.hardware.Camera和android.hardware.camera2去实现调用系统相机拍照和拍视频已经自定相机拍照和拍视频。
利用系统相机
不管是使用系统相机还是自定义相机,都需要取得相机使用的权限,如果需要保存拍下的图片还需要申请存储权限,权限申请如下:
1. AndroidManifest.xml加入:
<manifest ... ><uses-feature android:name="android.hardware.camera"android:required="true" /><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />...
</manifest>
调用系统相机拍照
获取小图标
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
在startActivityForResult()方法之前调用了resolveActivity(),这个方法返回第一个可以处理这个Intent的Activity,如果不做判断,没有Activity处理的话APP有可能会挂掉。
系统相机返回的数据依然在onActivityResult(int requestCode, int resultCode, Intent data)回调方法里面,下面拿到这个拍照返回数据并显示在ImageView上面:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {Bundle extras = data.getExtras();Bitmap imageBitmap = (Bitmap) extras.get("data");mImageView.setImageBitmap(imageBitmap);}
}
效果如图:
获取全尺寸图片
可以看到拍照得到的图片很小,因为没做任何配置,所以这种拍照方式系统默认返回的图片只适合做一个ICON。如果希望得到一个全尺寸的图片需要在前面拍照的基础上做一些修改。
1、首先修改调用系统相机的Intent
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(getPackageManager()) != null) {File photoFile = null;try {photoFile = createImageFile();} catch (IOException ex) {}if (photoFile != null) {//注意这里的com.example.wangc.myapplication.fileprovider一定要和Manifest文件中provider配置的一致Uri photoURI = FileProvider.getUriForFile(this,"com.example.wangc.myapplication.fileprovider",photoFile);takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);}}
2、然后在AndroidManifest.xml中加入FileProvider配置
<provider
android:name="android.support.v4.content.FileProvider"android:authorities="com.example.wangc.myapplication.fileprovider"android:exported="false"android:grantUriPermissions="true"><meta-data
android:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths"></meta-data>
</provider>
3、再新建file_paths文件
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="my_images" path="Android/data/com.example.wangc.myapplication/files/Pictures" />
</paths>
这里就涉及到了Android 7.0之后的文件系统修改,不熟悉的可以看官网。
4、最后依然是在onActivityResult中获取拍照得到的图片
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath);mImageView.setImageBitmap(bitmap);}
}
效果如图:
添加到相册
系统相机拍视频
调用系统相机拍视频
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {startActivityForResult(takeVideoIntent, REQUEST_VIDEO_CAPTURE);}
获取返回的视频
if (requestCode == REQUEST_VIDEO_CAPTURE && resultCode == RESULT_OK){Uri videoUri = data.getData();mVideoView.setVideoURI(videoUri);mVideoView.start();
}
视频文件太大不上传效果图了。
自定义相机
当需要在拍照预览界面添加上一些项目自身界面元素的时候系统相机就不能满足需要了,这是就需要用到自定义相机拍照。
自定义相机拍照
要实现自定义相机总的要完成以下几个步骤:
1、监测设备是否有相机可使用
2、利用SurfaceView创建拍照时预览界面
3、完成拍照
4、保存拍照文件
5、释放相机资源
监测设备是否有相机可使用
private boolean checkCameraHardware(Context context) {if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){// this device has a camerareturn true;} else {// no camera on this devicereturn false;}
}
利用SurfaceView创建拍照时预览界面
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {private SurfaceHolder mHolder;private Camera mCamera;public CameraPreview(Context context, Camera camera) {super(context);mCamera = camera;mHolder = getHolder();mHolder.addCallback(this);mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);}public void surfaceCreated(SurfaceHolder holder) {try {mCamera.setPreviewDisplay(holder);mCamera.startPreview();} catch (IOException e) {Log.d("+++", "Error setting camera preview: " + e.getMessage());}}public void surfaceDestroyed(SurfaceHolder holder) {}public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {if (mHolder.getSurface() == null){return;}try {mCamera.stopPreview();} catch (Exception e){}try {mCamera.setPreviewDisplay(mHolder);mCamera.startPreview();} catch (Exception e){Log.d("+++", "Error starting camera preview: " + e.getMessage());}}}
拍照并且在回调方法中保存文件
//获取相机实例mCamera = getCameraInstance();mPreview = new CameraPreview(this, mCamera);FrameLayout preview = findViewById(R.id.camera_preview);preview.addView(mPreview);Button captureButton = findViewById(R.id.button_capture);captureButton.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mCamera.takePicture(null, null, mPicture);}});/*** 拍照回调*/private Camera.PictureCallback mPicture = new Camera.PictureCallback() {@Overridepublic void onPictureTaken(byte[] data, Camera camera) {//保存返回的文件File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);if (pictureFile == null){Log.d("+++", "Error creating media file, check storage permissions: " );return;}try {FileOutputStream fos = new FileOutputStream(pictureFile);fos.write(data);fos.close();} catch (FileNotFoundException e) {Log.d("+++", "File not found: " + e.getMessage());} catch (IOException e) {Log.d("+++", "Error accessing file: " + e.getMessage());}}};/***保存文件* @return*/private static File getOutputMediaFile(int type){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;}}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;}
最后释放相机资源
private void releaseCamera(){if (mCamera != null){mCamera.release(); // release the camera for other applicationsmCamera = null;}}
效果如图:
这里只是完成了简单的自定义拍照流程,还有很多细节需要注意,比如要先通过getSupportedPreviewSizes()获取相机最佳预览尺寸,然后通过setPreviewSize()方法设置,不然就会出现预览模糊或者变形的情况。
Android最新相机(Camera)拍照、拍视频全面总结相关推荐
- android 调用 系统 相机 摄像机 拍照 拍视频
主要内容如下: 系统现有相机应用的调用 系统现有相机拍摄照片 获取系统现有相机拍摄的图片 系统现有相机拍摄图片Demo 系统现有相机拍摄视频 系统现有相机拍摄视频Demo 系统现有相机应用的调用 对于 ...
- Android Studio:使用Camera拍照(三)为相机增加取景蒙板/浮层
写在前面的话:每一个实例的代码都会附上相应的代码片或者图片,保证代码完整展示在博客中.最重要的是保证例程的完整性!!!方便自己也方便他人~欢迎大家交流讨论~本文为博主原创文章,未经博主允许不得转载. ...
- Android开发技巧——Camera拍照功能
本篇是我对开发项目的拍照功能过程中,对Camera拍照使用的总结.由于camera2是在api level 21(5.0.1)才引入的,而Camera到6.0仍可使用,所以暂未考虑camera2. 文 ...
- android 打开相机拍照功能吗,Android调用相机实现拍照功能
引言 在Android开发中相信大家都会遇到修改用户头像的问题,用户信息常常包含用户头像,一般流程为:默认头像-->用户修改(拍照/相册选择)-->保存头像图片. 本期我们就来实现调用系统 ...
- android 5 相机,camera fv-5
极致相机Camera FV-5是手机专业相机,一款为安卓手机用户开发的专业摄像软件,让你的手机享受单反的手动操作,手机也成为专业的相机,参数非常多,足以让你拥有单反的感觉. Camera FV-5是一 ...
- uniapp webview 直接调用原生摄像头拍照 拍视频 img video,通过ajax获取blob(file为特殊的blob)对象并上传到后端服务器
web-view中通过plus方法调用摄像头拍照或者拍视频并上传后端的操作步骤如下 plus.camera.getCamera()获取摄像头对象 cmr cmr.captureImage(callba ...
- android 自定义相机Camera
转载请标明来自:http://blog.csdn.net/qq_38416326/article/details/70809754 项目中,有时系统的相机不能满足我们的需求,例如:实现美图,这样就需要 ...
- Android 自定义相机Camera流程
demo 下载 android Camera 如何 获取最佳合适的尺寸 1.如何利用 Camera 开发自定义相机? a.Camera.getNumberOfCameras() 获取 相机数目返回一个 ...
- Android平台美颜相机/Camera实时滤镜/视频编解码/影像后期/人脸技术探索——1.1 工程思路与难点
回到目录 本文主要探讨搭建一款Android平台下美颜相机可能需要填的坑,内容会不断更新.. 相机框架 相机框架相对比较简单,现有的开源代码很多,可以很容易的实现拍照和录像的功能. 预览尺寸选择 预览 ...
最新文章
- python opencv读取网络图片
- 登录MOSS站点失败
- gitlab的日常使用
- expdp / impdp 用法详解(Oracle)
- VTK:绘图之PieChartActor
- win8计算机安全模式,WIN8如何设置按F8进入安全模式
- 开源Elasticsearch云托管服务,专享企业级服务
- 【CCF】201409-2 画图
- GDB调试带参数argc argv的程序
- appium 原理解析
- go语言介绍及应用场景分析
- android mapabc 地图 无法 拖动、缩放问题
- BUUCTF[SCTF2019]Who is he题解
- 【小万出生记——第3篇】小万升级为家用服务机器人
- identifier标签语句
- 基于人脸识别的课堂考勤系统 tkinter+openpyxl+face_recognition
- 不缺流量的罗永浩、李佳琦们,为啥深耕企业微信社群?
- linux如何切换任务,linux 0.11中简单的任务切换中遇到的问题
- 2022危险化学品生产单位安全生产管理人员考题及在线模拟考试
- Java(学习笔记三,kk自用)
热门文章
- 猎豹傅盛 :移动互联网的大航海时代来临
- QT(5.14.2) 部分文档中文译文
- 管螺纹如何标注_老师!请问这种螺纹孔怎么标注啊??机械设计教程螺纹知识教学!...
- 【运维心得】双宽带热备方案推荐
- 【愚公系列】2021年11月 攻防世界-进阶题-MISC-041(Become_a_Rockstar)
- 2020年会是大牛市的起点吗?
- c/c++单链表面试题—链表带环问题
- win10 蓝牙耳机 麦克风不可用
- win7系统设置虚拟内存的方法(附图文)
- Python_week04