Android 相机拍照的注意事项和基本使用请点击——Android Camera开发之基础知识篇
本文主要介绍Camera在项目中的代码实现:(经测试可用)
package com.wj.shoes.shortvideo.view.fragment.photo;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapRegionDecoder;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.ScaleAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.Toast;
import com.wj.shoes.R;
import com.wj.shoes.common.MyApplication;
import com.wj.shoes.shortvideo.utils.ImageUtils;
import com.wj.shoes.shortvideo.utils.camera.CameraHelper;
import com.wj.shoes.shortvideo.utils.camera.FileUtils;
import com.wj.shoes.shortvideo.utils.camera.IOUtil;
import com.wj.shoes.shortvideo.utils.camera.StringUtils;
import com.wj.shoes.shortvideo.view.activity.shortvideo.circle_activity_camera_sticker.CircleCameraStickerActivity;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import butterknife.ButterKnife;
/**
* 照相
*/
public class PhotoFragment extends Fragment implements View.OnClickListener, View.OnTouchListener{
private View mView;
//预览画面
private SurfaceView sfv_show_frame;
//拍照
private ImageView iv_photograph;
//切换摄像头
private ImageView iv_switch_camera;
//切换闪光灯模式
private ImageView iv_flash_lamp;
private CameraHelper mCameraHelper;
private View v_focus_index;
private Camera cameraInst = null;
private Camera.Parameters parameters = null;
private int PHOTO_SIZE = 2000;
//1是前置 0是后置
private int mCurrentCameraId = 0;
private Bundle bundle = null;
//前后置摄像头切换
private float pointX, pointY;
static final int FOCUS = 1;// 聚焦
static final int ZOOM = 2;// 缩放
private int mode; //0是聚焦 1是放大
private float dist;
private Handler handler = new Handler();
private SurfaceHolder surfaceHolder=null;
private SurfaceCallback surfaceCallback=null;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (mView == null) {
mView = inflater.inflate(R.layout.mgx_fragment_photo, container, false);
mCameraHelper = new CameraHelper(getActivity());
checkCameraHardware(getActivity());
}
return mView;
}
//检查该设备是否有摄像头
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
initView();
return true;
} else {
Toast.makeText(getActivity(), "该设备没有摄像头", Toast.LENGTH_LONG).show();
return false;
}
}
private void initView() {
sfv_show_frame = (SurfaceView) mView.findViewById(R.id.sfv_show_frame);
sfv_show_frame.setOnTouchListener(this);
sfv_show_frame.setOnClickListener(this);
iv_photograph = (ImageView) mView.findViewById(R.id.iv_photograph);
iv_photograph.setOnClickListener(this);
iv_switch_camera = (ImageView) mView.findViewById(R.id.iv_switch_camera);
iv_switch_camera.setOnClickListener(this);
iv_flash_lamp = (ImageView) mView.findViewById(R.id.iv_flash_lamp);
iv_flash_lamp.setOnClickListener(this);
v_focus_index = (View) mView.findViewById(R.id.v_focus_index);
v_focus_index.setOnClickListener(this);
//初始化相机
surfaceHolder = sfv_show_frame.getHolder();
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
surfaceHolder.setKeepScreenOn(true);
sfv_show_frame.setFocusable(true);
//TRIM_MEMORY_BACKGROUND ComponentCallbacks2 TRIM_MEMORY_BACKGROUND=40
sfv_show_frame.setBackgroundColor(40);
SurfaceCallback surfaceCallback=new SurfaceCallback();
//为SurfaceView的句柄添加一个回调函数
sfv_show_frame.getHolder().addCallback(surfaceCallback);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//拍照
case R.id.iv_photograph:
cameraInst.takePicture(null, null, new MyPictureCallback());
break;
//切换摄像头
case R.id.iv_switch_camera:
switchCamera();
break;
//切换闪光灯
case R.id.iv_flash_lamp:
turnLight(cameraInst);
break;
//点击显示画面
case R.id.sfv_show_frame:
focusFrame();
break;
}
}
//聚焦框
private void focusFrame() {
try {
pointFocus((int) pointX, (int) pointY);
} catch (Exception e) {
e.printStackTrace();
}
FrameLayout.LayoutParams layout = new FrameLayout.LayoutParams(v_focus_index.getLayoutParams());
layout.setMargins((int) pointX - 60, (int) pointY - 60, 0, 0);
//surface view初始化时大小的设置
v_focus_index.setLayoutParams(layout);
v_focus_index.setVisibility(View.VISIBLE);
ScaleAnimation sa = new ScaleAnimation(3f, 1f, 3f, 1f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f, ScaleAnimation.RELATIVE_TO_SELF, 0.5f);
sa.setDuration(800);
v_focus_index.startAnimation(sa);
handler.postDelayed(new Runnable() {
@Override
public void run() {
v_focus_index.setVisibility(View.INVISIBLE);
}
}, 800);
}
/**
* 缩放
*
* @param view
* @param motionEvent
* @return
*/
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
// 主点按下
case MotionEvent.ACTION_DOWN:
pointX = motionEvent.getX();
pointY = motionEvent.getY();
mode = FOCUS;
break;
// 副点按下
case MotionEvent.ACTION_POINTER_DOWN:
dist = spacing(motionEvent);
// 如果连续两点距离大于10,则判定为多点模式
if (spacing(motionEvent) > 10f) {
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = FOCUS;
break;
case MotionEvent.ACTION_MOVE:
if (mode == FOCUS) {
//pointFocus((int) event.getRawX(), (int) event.getRawY());
} else if (mode == ZOOM) {
float newDist = spacing(motionEvent);
if (newDist > 10f) {
float tScale = (newDist - dist) / dist;
if (tScale < 0) {
tScale = tScale * 10;
}
addZoomIn((int) tScale);
}
}
break;
}
return false;
}
/**
* 两点的距离
*/
private float spacing(MotionEvent event) {
if (event == null) {
return 0;
}
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return (float) Math.sqrt(x * x + y * y);
}
//放大缩小
int curZoomValue = 0;
private void addZoomIn(int delta) {
try {
Camera.Parameters params = cameraInst.getParameters();
Log.d("Camera", "Is support Zoom " + params.isZoomSupported());
if (!params.isZoomSupported()) {
return;
}
curZoomValue += delta;
if (curZoomValue < 0) {
curZoomValue = 0;
} else if (curZoomValue > params.getMaxZoom()) {
curZoomValue = params.getMaxZoom();
}
if (!params.isSmoothZoomSupported()) {
params.setZoom(curZoomValue);
cameraInst.setParameters(params);
return;
} else {
cameraInst.startSmoothZoom(curZoomValue);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//定点对焦的代码
private void pointFocus(int x, int y) {
cameraInst.cancelAutoFocus();
parameters = cameraInst.getParameters();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
showPoint(x, y);
}
cameraInst.setParameters(parameters);
autoFocus();
}
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
private void showPoint(int x, int y) {
if (parameters.getMaxNumMeteringAreas() > 0) {
List<Camera.Area> areas = new ArrayList<Camera.Area>();
//xy变换了
int rectY = -x * 2000 / MyApplication.getApp().getScreenWidth() + 1000;
int rectX = y * 2000 / MyApplication.getApp().getScreenHeight() - 1000;
int left = rectX < -900 ? -1000 : rectX - 100;
int top = rectY < -900 ? -1000 : rectY - 100;
int right = rectX > 900 ? 1000 : rectX + 100;
int bottom = rectY > 900 ? 1000 : rectY + 100;
Rect area1 = new Rect(left, top, right, bottom);
areas.add(new Camera.Area(area1, 800));
parameters.setMeteringAreas(areas);
}
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);
}
private final class MyPictureCallback implements Camera.PictureCallback {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
bundle = new Bundle();
//将图片字节数据保存在bundle当中,实现数据交换
bundle.putByteArray("bytes", data);
new SavePicTask(data).execute();
// 拍完照后,重新开始预览
camera.startPreview();
}
}
/**
* 异步线程更新图片
*/
private class SavePicTask extends AsyncTask<Void, Void, String> {
private byte[] data;
protected void onPreExecute() {
Log.d(TAG, "onPreExecute: ------------处理中------------");
}
//拍摄完成后的照片
SavePicTask(byte[] data) {
this.data = data;
}
@Override
protected String doInBackground(Void... params) {
try {
return saveToSDCard(data);
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (StringUtils.isNotEmpty(result)) {
} else {
Toast.makeText(getActivity(), "拍照失败,请稍后重试!", Toast.LENGTH_SHORT).show();
}
}
}
/**
* SurfaceCallback
*/
private final class SurfaceCallback implements SurfaceHolder.Callback {
public void surfaceDestroyed(SurfaceHolder holder) {
try {
if (cameraInst != null) {
//停止预览
cameraInst.stopPreview();
cameraInst.release();
cameraInst = null;
}
} catch (Exception e) {
//相机已经关了
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (null == cameraInst) {
try {
cameraInst = Camera.open();
cameraInst.setPreviewDisplay(holder);
initCamera();
cameraInst.startPreview();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
//屏幕发生变化时进行调用
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
autoFocus();
}
}
//实现自动对焦
private void autoFocus() {
new Thread() {
@Override
public void run() {
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (cameraInst == null) {
return;
}
cameraInst.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
//实现相机的参数初始化
initCamera();
}
}
});
}
};
}
/**
* 获取相机的预览尺寸
*/
private Camera.Size adapterSize = null;
private Camera.Size previewSize = null;
private void initCamera() {
parameters = cameraInst.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
//if (adapterSize == null) {
setUpPicSize(parameters);
setUpPreviewSize(parameters);
//}
if (adapterSize != null) {
parameters.setPictureSize(previewSize.width, previewSize.height);
}
//设置比例尺寸
if (previewSize != null) {
parameters.setPreviewSize(previewSize.width, previewSize.height);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
//1连续对焦
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
} else {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
setDispaly(parameters, cameraInst);
try {
cameraInst.setParameters(parameters);
} catch (Exception e) {
e.printStackTrace();
}
cameraInst.startPreview();
// 2如果要实现连续的自动对焦,这一句必须加上
cameraInst.cancelAutoFocus();
}
private void setUpPicSize(Camera.Parameters parameters) {
if (adapterSize != null) {
return;
} else {
adapterSize = findBestPictureResolution();
return;
}
}
private void setUpPreviewSize(Camera.Parameters parameters) {
if (previewSize != null) {
return;
} else {
previewSize = findBestPreviewResolution();
}
}
/**
* 最小预览界面的分辨率
*/
private static final int MIN_PREVIEW_PIXELS = 480 * 320;
/**
* 最大宽高比差
*/
private static final double MAX_ASPECT_DISTORTION = 0.15;
private static final String TAG = "Camera";
/**
* 找出最适合的预览界面分辨率
*/
private Camera.Size findBestPreviewResolution() {
Camera.Parameters cameraParameters = cameraInst.getParameters();
Camera.Size defaultPreviewResolution = cameraParameters.getPreviewSize();
List<Camera.Size> rawSupportedSizes = cameraParameters.getSupportedPreviewSizes();
if (rawSupportedSizes == null) {
return defaultPreviewResolution;
}
// 按照分辨率从大到小排序
List<Camera.Size> supportedPreviewResolutions = new ArrayList<Camera.Size>(rawSupportedSizes);
Collections.sort(supportedPreviewResolutions, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size a, Camera.Size b) {
int aPixels = a.height * a.width;
int bPixels = b.height * b.width;
if (bPixels < aPixels) {
return -1;
}
if (bPixels > aPixels) {
return 1;
}
return 0;
}
});
StringBuilder previewResolutionSb = new StringBuilder();
for (Camera.Size supportedPreviewResolution : supportedPreviewResolutions) {
previewResolutionSb.append(supportedPreviewResolution.width).append('x').append(supportedPreviewResolution.height).append(' ');
}
Log.v(TAG, "Supported preview resolutions: " + previewResolutionSb);
// 移除不符合条件的分辨率
double screenAspectRatio = (double) MyApplication.getApp().getScreenWidth() / (double) MyApplication.getApp().getScreenHeight();
Iterator<Camera.Size> it = supportedPreviewResolutions.iterator();
while (it.hasNext()) {
Camera.Size supportedPreviewResolution = it.next();
int width = supportedPreviewResolution.width;
int height = supportedPreviewResolution.height;
// 移除低于下限的分辨率,尽可能取高分辨率
if (width * height < MIN_PREVIEW_PIXELS) {
it.remove();
continue;
}
// 在camera分辨率与屏幕分辨率宽高比不相等的情况下,找出差距最小的一组分辨率
// 由于camera的分辨率是width>height,我们设置的portrait模式中,width<height
// 因此这里要先交换然preview宽高比后在比较
boolean isCandidatePortrait = width > height;
int maybeFlippedWidth = isCandidatePortrait ? height : width;
int maybeFlippedHeight = isCandidatePortrait ? width : height;
double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;
double distortion = Math.abs(aspectRatio - screenAspectRatio);
if (distortion > MAX_ASPECT_DISTORTION) {
it.remove();
continue;
}
// 找到与屏幕分辨率完全匹配的预览界面分辨率直接返回
if (maybeFlippedWidth == MyApplication.getApp().getScreenWidth() && maybeFlippedHeight == MyApplication.getApp().getScreenHeight()) {
return supportedPreviewResolution;
}
}
// 如果没有找到合适的,并且还有候选的像素,则设置其中最大比例的,对于配置比较低的机器不太合适
if (!supportedPreviewResolutions.isEmpty()) {
Camera.Size largestPreview = supportedPreviewResolutions.get(0);
return largestPreview;
}
// 没有找到合适的,就返回默认的
return defaultPreviewResolution;
}
private Camera.Size findBestPictureResolution() {
Camera.Parameters cameraParameters = cameraInst.getParameters();
// 至少会返回一个值
List<Camera.Size> supportedPicResolutions = cameraParameters.getSupportedPictureSizes();
StringBuilder picResolutionSb = new StringBuilder();
for (Camera.Size supportedPicResolution : supportedPicResolutions) {
picResolutionSb.append(supportedPicResolution.width).append('x')
.append(supportedPicResolution.height).append(" ");
}
Log.d(TAG, "Supported picture resolutions: " + picResolutionSb);
Camera.Size defaultPictureResolution = cameraParameters.getPictureSize();
Log.d(TAG, "default picture resolution " + defaultPictureResolution.width + "x" + defaultPictureResolution.height);
// 排序
List<Camera.Size> sortedSupportedPicResolutions = new ArrayList<Camera.Size>(supportedPicResolutions);
Collections.sort(sortedSupportedPicResolutions, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size a, Camera.Size b) {
int aPixels = a.height * a.width;
int bPixels = b.height * b.width;
if (bPixels < aPixels) {
return -1;
}
if (bPixels > aPixels) {
return 1;
}
return 0;
}
});
// 移除不符合条件的分辨率
double screenAspectRatio = (double) MyApplication.getApp().getScreenWidth() / (double) MyApplication.getApp().getScreenHeight();
Iterator<Camera.Size> it = sortedSupportedPicResolutions.iterator();
while (it.hasNext()) {
Camera.Size supportedPreviewResolution = it.next();
int width = supportedPreviewResolution.width;
int height = supportedPreviewResolution.height;
// 在camera分辨率与屏幕分辨率宽高比不相等的情况下,找出差距最小的一组分辨率
// 由于camera的分辨率是width>height,我们设置的portrait模式中,width<height
// 因此这里要先交换然后在比较宽高比
boolean isCandidatePortrait = width > height;
int maybeFlippedWidth = isCandidatePortrait ? height : width;
int maybeFlippedHeight = isCandidatePortrait ? width : height;
double aspectRatio = (double) maybeFlippedWidth / (double) maybeFlippedHeight;
double distortion = Math.abs(aspectRatio - screenAspectRatio);
if (distortion > MAX_ASPECT_DISTORTION) {
it.remove();
continue;
}
}
// 如果没有找到合适的,并且还有候选的像素,对于照片,则取其中最大比例的,而不是选择与屏幕分辨率相同的
if (!sortedSupportedPicResolutions.isEmpty()) {
return sortedSupportedPicResolutions.get(0);
}
// 没有找到合适的,就返回默认的
return defaultPictureResolution;
}
//控制图像的正确显示方向
private void setDispaly(Camera.Parameters parameters, Camera camera) {
if (Build.VERSION.SDK_INT >= 8) {
setDisplayOrientation(camera, 90);
} else {
parameters.setRotation(90);
}
}
//实现的图像的正确显示
private void setDisplayOrientation(Camera camera, int i) {
Method downPolymorphic;
try {
downPolymorphic = camera.getClass().getMethod("setDisplayOrientation",
new Class[]{int.class});
if (downPolymorphic != null) {
downPolymorphic.invoke(camera, new Object[]{i});
}
} catch (Exception e) {
Log.e("Came_e", "图像出错");
}
}
/**
* 将拍下来的照片存放在SD卡中
*
* @param data
* @throws IOException
*/
public String saveToSDCard(byte[] data) throws IOException {
Bitmap croppedImage;
//获得图片大小
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, options);
PHOTO_SIZE = options.outHeight > options.outWidth ? options.outWidth : options.outHeight;
int height = options.outHeight > options.outWidth ? options.outHeight : options.outWidth;
options.inJustDecodeBounds = false;
Rect r;
if (mCurrentCameraId == 1) {
r = new Rect(height - PHOTO_SIZE, 0, height, PHOTO_SIZE);
} else {
r = new Rect(0, 0, PHOTO_SIZE, PHOTO_SIZE);
}
try {
croppedImage = decodeRegionCrop(data, r);
} catch (Exception e) {
return null;
}
//照片存放的路径
String imagePath = ImageUtils.saveToFile(FileUtils.getInst().getSystemPhotoPath(), true, croppedImage);
croppedImage.recycle();
//拍好的照片带入到CircleCameraStickerActivity
Intent intent = new Intent(getActivity(), CircleCameraStickerActivity.class);
intent.putExtra("photoImage", imagePath);
startActivity(intent);
return imagePath;
}
private Bitmap decodeRegionCrop(byte[] data, Rect rect) {
InputStream is = null;
System.gc();
Bitmap croppedImage = null;
try {
is = new ByteArrayInputStream(data);
BitmapRegionDecoder decoder = BitmapRegionDecoder.newInstance(is, false);
try {
croppedImage = decoder.decodeRegion(rect, new BitmapFactory.Options());
} catch (IllegalArgumentException e) {
}
} catch (Throwable e) {
e.printStackTrace();
} finally {
IOUtil.closeStream(is);
}
Matrix m = new Matrix();
m.setRotate(90, PHOTO_SIZE / 2, PHOTO_SIZE / 2);
if (mCurrentCameraId == 1) {
m.postScale(1, -1);
}
Bitmap rotatedImage = Bitmap.createBitmap(croppedImage, 0, 0, PHOTO_SIZE, PHOTO_SIZE, m, true);
if (rotatedImage != croppedImage)
croppedImage.recycle();
return rotatedImage;
}
/**
* 闪光灯开关 开->关->自动
*
* @param mCamera
*/
private void turnLight(Camera mCamera) {
if (mCamera == null || mCamera.getParameters() == null
|| mCamera.getParameters().getSupportedFlashModes() == null) {
return;
}
Camera.Parameters parameters = mCamera.getParameters();
String flashMode = mCamera.getParameters().getFlashMode();
List<String> supportedModes = mCamera.getParameters().getSupportedFlashModes();
if (Camera.Parameters.FLASH_MODE_OFF.equals(flashMode)
&& supportedModes.contains(Camera.Parameters.FLASH_MODE_ON)) {//关闭状态
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
mCamera.setParameters(parameters);
iv_flash_lamp.setImageResource(R.mipmap.mgx_camera_open_flash_lamp);
} else if (Camera.Parameters.FLASH_MODE_ON.equals(flashMode)) {//开启状态
if (supportedModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
iv_flash_lamp.setImageResource(R.mipmap.mgx_camera_auto_flash_lamp);
mCamera.setParameters(parameters);
} else if (supportedModes.contains(Camera.Parameters.FLASH_MODE_OFF)) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
iv_flash_lamp.setImageResource(R.mipmap.mgx_camera_close_flash_lamp);
mCamera.setParameters(parameters);
}
} else if (Camera.Parameters.FLASH_MODE_AUTO.equals(flashMode)
&& supportedModes.contains(Camera.Parameters.FLASH_MODE_OFF)) {
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
mCamera.setParameters(parameters);
iv_flash_lamp.setImageResource(R.mipmap.mgx_camera_close_flash_lamp);
}
}
//切换前后置摄像头
private void switchCamera() {
mCurrentCameraId = (mCurrentCameraId + 1) % mCameraHelper.getNumberOfCameras();
releaseCamera();
Log.d("DDDD", "DDDD----mCurrentCameraId" + mCurrentCameraId);
setUpCamera(mCurrentCameraId);
}
/**
* 释放摄像头
*/
public void releaseCamera() {
if (cameraInst != null) {
//停止预览
cameraInst.stopPreview();
cameraInst.release();
surfaceHolder.removeCallback(surfaceCallback);
cameraInst = null;
}
}
/**
* 开始预览
*/
public void tartPreview() {
if (null == cameraInst) {
try {
cameraInst = Camera.open();
cameraInst.setPreviewDisplay(sfv_show_frame.getHolder());
initCamera();
cameraInst.startPreview();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
/**
* @param mCurrentCameraId2
*/
private void setUpCamera(int mCurrentCameraId2) {
cameraInst = getCameraInstance(mCurrentCameraId2);
if (cameraInst != null) {
try {
cameraInst.setPreviewDisplay(sfv_show_frame.getHolder());
initCamera();
cameraInst.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
} else {
Log.d(TAG, "setUpCamera: -------切换失败,请重试!---------");
}
}
/**
* 获取摄像头的id
*
* @param id
* @return
*/
private Camera getCameraInstance(final int id) {
Camera c = null;
try {
c = mCameraHelper.openCamera(id);
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
}
package com.wj.shoes.shortvideo.utils.camera;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.view.Surface;
import static android.os.Build.VERSION.SDK_INT;
import static android.os.Build.VERSION_CODES.GINGERBREAD;
/**
* Created by A-23 on 2018/6/9.
*/
public class CameraHelper {
private final CameraHelperImpl mImpl;
public CameraHelper(final Context context) {
if (SDK_INT >= GINGERBREAD) {
mImpl = new CameraHelperGB();
} else {
mImpl = new CameraHelperBase(context);
}
}
public interface CameraHelperImpl {
int getNumberOfCameras();
Camera openCamera(int id);
Camera openDefaultCamera();
Camera openCameraFacing(int facing);
boolean hasCamera(int cameraFacingFront);
void getCameraInfo(int cameraId, CameraInfo2 cameraInfo);
}
public int getNumberOfCameras() {
return mImpl.getNumberOfCameras();
}
public Camera openCamera(final int id) {
return mImpl.openCamera(id);
}
public Camera openDefaultCamera() {
return mImpl.openDefaultCamera();
}
public Camera openFrontCamera() {
return mImpl.openCameraFacing(Camera.CameraInfo.CAMERA_FACING_FRONT);
}
public Camera openBackCamera() {
return mImpl.openCameraFacing(Camera.CameraInfo.CAMERA_FACING_BACK);
}
public boolean hasFrontCamera() {
return mImpl.hasCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
}
public boolean hasBackCamera() {
return mImpl.hasCamera(Camera.CameraInfo.CAMERA_FACING_BACK);
}
public void getCameraInfo(final int cameraId, final CameraInfo2 cameraInfo) {
mImpl.getCameraInfo(cameraId, cameraInfo);
}
public void setCameraDisplayOrientation(final Activity activity, final int cameraId,
final Camera camera) {
int result = getCameraDisplayOrientation(activity, cameraId);
camera.setDisplayOrientation(result);
}
public int getCameraDisplayOrientation(final Activity activity, final int cameraId) {
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;
CameraInfo2 info = new CameraInfo2();
getCameraInfo(cameraId, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
return result;
}
public static class CameraInfo2 {
public int facing;
public int orientation;
}
}