100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > android studio操作手机相机 Android Studio 调用Camera实现拍照功能

android studio操作手机相机 Android Studio 调用Camera实现拍照功能

时间:2021-10-01 18:59:31

相关推荐

android studio操作手机相机 Android Studio 调用Camera实现拍照功能

首先创建一个SurfaceHolder实现对SurfaceView的回调,然后重写SurfaceCreate函数,实现对Camera的初始化等一系列工作:代码如下: @Override

public void surfaceCreated(SurfaceHolder holder) {

Log.e("TAG","------surfaceCreated------");

try {

//这里我优先找后置摄像头,找不到再找前面的

int cameraIndex = findBackOrFrontCamera(Camera.CameraInfo.CAMERA_FACING_BACK);

if (cameraIndex == -1) {

cameraIndex = findBackOrFrontCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);

if (cameraIndex == -1) {

Log.e("TAG", "No Camera!");

currentCameraType = CAMERA_NOTEXIST;

currentCameraIndex = -1;

return;

} else {

currentCameraType = FRONT;

}

} else {

currentCameraType = BACK;

}

//找到想要的摄像头后,就打开

if (mCamera == null) {

mCamera = openCamera(currentCameraType);

}

} catch (Exception e) {

e.printStackTrace();

}

}

本例子中,我首先找到想要打开的摄像头,这里的优先寻找后置摄像头,如果没有找到,再找前置的,代码如下: /**

* 按要求查找摄像头

*

* @param camera_facing 按要求查找,镜头是前还是后

* @return -1表示找不到

*/

private int findBackOrFrontCamera(int camera_facing) {

int cameraCount = 0;

Camera.CameraInfo cameraInfo = new Camera.CameraInfo();

cameraCount = Camera.getNumberOfCameras();

for (int camIdx = 0; camIdx < cameraCount; camIdx++) {

Camera.getCameraInfo(camIdx, cameraInfo);

if (cameraInfo.facing == camera_facing) {

return camIdx;

}

}

return -1;

}

当找到摄像头后,便打开Camera,其实打开Camera可以直接用open(CameraId)函数即可,但我在重新封装了一下,直接帖代码: /**

* 按照type的类型打开相应的摄像头

*

* @param type 标志当前打开前还是后的摄像头

* @return 返回当前打开摄像机的对象

*/

private Camera openCamera(int type) {

int frontIndex = -1;

int backIndex = -1;

int cameraCount = Camera.getNumberOfCameras();

Camera.CameraInfo info = new Camera.CameraInfo();

for (int cameraIndex = 0; cameraIndex < cameraCount; cameraIndex++) {

Camera.getCameraInfo(cameraIndex, info);

if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {

frontIndex = cameraIndex;

} else if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {

backIndex = cameraIndex;

}

}

currentCameraType = type;

if (type == FRONT && frontIndex != -1) {

currentCameraIndex = frontIndex;

return Camera.open(frontIndex);

} else if (type == BACK && backIndex != -1) {

currentCameraIndex = backIndex;

return Camera.open(backIndex);

}

return null;

}

然后在SurfaceChange对Camera进行一系列初始化(对摄像头初始化,就是设定图片格式,图片尺寸等赋值,要打开摄像头才可以初始化,否则会报错) /**

* 初始化摄像头

* @param holder

*/

private void initCamera(SurfaceHolder holder){

Log.e("TAG","initCamera");

if (mPreviewRunning)

mCamera.stopPreview();

Camera.Parameters parameters;

try{

//获取预览的各种分辨率

parameters = mCamera.getParameters();

}catch (Exception e){

e.printStackTrace();

return;

}

//这里我设为480*800的尺寸

parameters.setPreviewSize(480,800);

// 设置照片格式

parameters.setPictureFormat(PixelFormat.JPEG);

//设置图片预览的格式

parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP);

setCameraDisplayOrientation(this,currentCameraIndex,mCamera);

try{

mCamera.setPreviewDisplay(holder);

}catch(Exception e){

if(mCamera != null){

mCamera.release();

mCamera = null;

}

e.printStackTrace();

}

mCamera.startPreview();

mPreviewRunning = true;

}

/**

* 设置旋转角度

* @param activity

* @param cameraId

* @param camera

*/

private void setCameraDisplayOrientation(Activity activity,int cameraId,Camera camera){

Camera.CameraInfo info = new Camera.CameraInfo();

Camera.getCameraInfo(cameraId,info);

int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

int degrees = 0;

switch(rotation){

case Surface.ROTATION_0:

degrees = 0;

break;

case Surface.ROTATION_90:

degrees = 90;

break;

case Surface.ROTATION_180:

degrees = 180;

break;

case Surface.ROTATION_270:

degrees = 270;

break;

}

int result;

if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){

result = (info.orientation + degrees) % 360;

result = (360 - result) % 360;

}else{

result = (info.orientation - degrees +360) % 360;

}

camera.setDisplayOrientation(result);

}

当这些工作完成后,便可以对当前摄像头捕捉的画面进行拍照了: /**

* 实现拍照功能

*/

public void takePhoto(){

Camera.Parameters parameters;

try{

parameters = mCamera.getParameters();

}catch(Exception e){

e.printStackTrace();

return;

}

//获取摄像头支持的各种分辨率,因为摄像头数组不确定是按降序还是升序,这里的逻辑有时不是很好找得到相应的尺寸

//可先确定是按升还是降序排列,再进对对比吧,我这里拢统地找了个,是个不精确的...

Listlist = parameters.getSupportedPictureSizes();

int size = 0;

for (int i =0 ;i < list.size() - 1;i++){

if (list.get(i).width >= 480){

//完美匹配

size = i;

break;

}

else{

//找不到就找个最接近的吧

size = i;

}

}

//设置照片分辨率,注意要在摄像头支持的范围内选择

parameters.setPictureSize(list.get(size).width,list.get(size).height);

//设置照相机参数

mCamera.setParameters(parameters);

//使用takePicture()方法完成拍照

mCamera.autoFocus(new Camera.AutoFocusCallback() {

//自动聚焦完成后拍照

@Override

public void onAutoFocus(boolean success, Camera camera) {

if (success && camera != null){

mCamera.takePicture(new ShutterCallback(), null, new Camera.PictureCallback() {

//拍照回调接口

@Override

public void onPictureTaken(byte[] data, Camera camera) {

savePhoto(data);

//停止预览

mCamera.stopPreview();

//重启预览

mCamera.startPreview();

}

});

}

}

});

}

/* *//**

* 快门回调接口,如果不想拍照声音,直接将new ShutterCallback()修改为null即可

*/

private class ShutterCallback implements Camera.ShutterCallback {

@Override

public void onShutter() {

MediaPlayer mPlayer = new MediaPlayer();

mPlayer = MediaPlayer.create(getApplicationContext(), R.raw.shutter);

try{

mPlayer.prepare();

}catch (IllegalStateException e){

e.printStackTrace();

}catch (IOException e){

e.printStackTrace();

}

mPlayer.start();

}

}

这里要注意下,有些手机调用onAutoFocus函数,会返回失败,因为如果该手机无自动对焦,则无法执行对焦成功后的函数了。。。

当捕捉到数据后,便可以将这些数据保存至设定的地方了: /**

* 设置照片的路径,具体路径可自定义

* @return

*/

private String setPicSaveFile(){

//创建保存的路径

File storageDir = getOwnCacheDirectory(this,"MyCamera/photos");

//返回自定义的路径

return storageDir.getPath();

}

private File getOwnCacheDirectory(Context context, String cacheDir) {

File appCacheDir = null;

//判断SD卡正常挂载并且拥有根限的时候创建文件

if(Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) &&

hasExternalStoragePermission(context)){

appCacheDir = new File(Environment.getExternalStorageDirectory(),cacheDir);

}

if (appCacheDir == null || !appCacheDir.exists() && !appCacheDir.mkdirs()){

appCacheDir = context.getCacheDir();

}

return appCacheDir;

}

/**

* 检查是否有权限

* @param context

* @return

*/

private boolean hasExternalStoragePermission(Context context) {

int permission = context.checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE");

//PERMISSION_GRANTED=0

return permission == 0;

}

由于调用了系统Camera和对SD卡读写,所以在AndroidManifest需要申请权限:

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。