Android仿最新微信自定義相機(長按拍攝,輕點拍照)
阿新 • • 發佈:2019-01-17
最近在開發即時通訊這個模組的時候使用到了自定義的相機,需求與微信一樣,要求相機能長按和輕點,當時在網上找自定義相機的資源,很少,所以,我在這裡把我的一些開發經驗貼出來,供大家學習。
大致完成的功能如下:
- 長按拍攝視訊,輕點拍照
- 前後攝像頭的切換
- 閃光的的開啟,關閉,自動
- 圖片的壓縮
- 自動聚焦,手動聚焦
效果圖如下:
相關程式碼如下:
package com.ses.im.app.chat.newcamera;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.PointF;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.Surface;
import android.view.TextureView;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import com.ses.im.app.chat.R;
import java.io.File;
import java.util.concurrent.TimeUnit;
import rx.Observable;
import rx.Subscriber;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.schedulers.Schedulers;
/**
*
* 拍攝介面
*/
public class CameraActivity extends AppCompatActivity implements View.OnClickListener {
/**
* 獲取相簿
*/
public static final int REQUEST_PHOTO = 1;
/**
* 獲取視訊
*/
public static final int REQUEST_VIDEO = 2;
/**
* 最小錄製時間
*/
private static final int MIN_RECORD_TIME = 1 * 1000;
/**
* 最長錄製時間
*/
private static final int MAX_RECORD_TIME = 15 * 1000;
/**
* 重新整理進度的間隔時間
*/
private static final int PLUSH_PROGRESS = 100;
private Context mContext;
/**
* TextureView
*/
private TextureView mTextureView;
/**
* 帶手勢識別
*/
private CameraView mCameraView;
/**
* 錄製按鈕
*/
private CameraProgressBar mProgressbar;
/**
* 頂部像機設定
*/
private RelativeLayout rl_camera;
/**
* 關閉,選擇,前後置
*/
private ImageView iv_close, iv_facing;
private RelativeLayout iv_choice;
private RelativeLayout cancel;
/**
* 閃光
*/
private TextView tv_flash;
/**
* camera manager
*/
private CameraManager cameraManager;
/**
* player manager
*/
private MediaPlayerManager playerManager;
/**
* true代表視訊錄製,否則拍照
*/
private boolean isSupportRecord;
/**
* 視訊錄製地址
*/
private String recorderPath;
/**
* 圖片地址
*/
private String photoPath;
/**
* 錄製視訊的時間,毫秒
*/
private int recordSecond;
/**
* 獲取照片訂閱, 進度訂閱
*/
private Subscription takePhotoSubscription, progressSubscription;
/**
* 是否正在錄製
*/
private boolean isRecording;
/**
* 是否為點了拍攝狀態(沒有拍照預覽的狀態)
*/
private boolean isPhotoTakingState;
public static void lanuchForPhoto(Activity context) {
Intent intent = new Intent(context, CameraActivity.class);
context.startActivityForResult(intent, REQUEST_PHOTO);
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_camera);
initView();
initDatas();
}
private void initView() {
mTextureView = (TextureView) findViewById(R.id.mTextureView);
mCameraView = (CameraView) findViewById(R.id.mCameraView);
mProgressbar = (CameraProgressBar) findViewById(R.id.mProgressbar);
rl_camera = (RelativeLayout) findViewById(R.id.rl_camera);
iv_close = (ImageView) findViewById(R.id.iv_close);
iv_close.setOnClickListener(this);
iv_choice = (RelativeLayout) findViewById(R.id.iv_choice);
iv_choice.setOnClickListener(this);
iv_close.setOnClickListener(this);
iv_facing = (ImageView) findViewById(R.id.iv_facing);
iv_facing.setOnClickListener(this);
iv_close.setOnClickListener(this);
tv_flash = (TextView) findViewById(R.id.tv_flash);
tv_flash.setOnClickListener(this);
cancel= (RelativeLayout) findViewById(R.id.cancel);
cancel.setOnClickListener(this);
}
protected void initDatas() {
cameraManager = CameraManager.getInstance(getApplication());
playerManager = MediaPlayerManager.getInstance(getApplication());
cameraManager.setCameraType(isSupportRecord ? 1 : 0);
tv_flash.setVisibility(cameraManager.isSupportFlashCamera() ? View.VISIBLE : View.GONE);
setCameraFlashState();
iv_facing.setVisibility(cameraManager.isSupportFrontCamera() ? View.VISIBLE : View.GONE);
rl_camera.setVisibility(cameraManager.isSupportFlashCamera()
|| cameraManager.isSupportFrontCamera() ? View.VISIBLE : View.GONE);
final int max = MAX_RECORD_TIME / PLUSH_PROGRESS;
mProgressbar.setMaxProgress(max);
/**
* 拍照,拍攝按鈕監聽
*/
mProgressbar.setOnProgressTouchListener(new CameraProgressBar.OnProgressTouchListener() {
@Override
public void onClick(CameraProgressBar progressBar) {
cameraManager.takePhoto(callback);
isSupportRecord = false;
}
@Override
public void onLongClick(CameraProgressBar progressBar) {
isSupportRecord = true;
cameraManager.setCameraType(1);
rl_camera.setVisibility(View.GONE);
recorderPath = FileUtils.getUploadVideoFile(mContext);
cameraManager.startMediaRecord1(recorderPath);
isRecording = true;
progressSubscription = Observable.interval(100, TimeUnit.MILLISECONDS, AndroidSchedulers.mainThread()).take(max).subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
stopRecorder(true);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Long aLong) {
mProgressbar.setProgress(mProgressbar.getProgress() + 1);
}
});
}
@Override
public void onZoom(boolean zoom) {
cameraManager.handleZoom(zoom);
}
@Override
public void onLongClickUp(CameraProgressBar progressBar) {
// isSupportRecord = false;
cameraManager.setCameraType(0);
stopRecorder(true);
if (progressSubscription != null) {
progressSubscription.unsubscribe();
}
}
@Override
public void onPointerDown(float rawX, float rawY) {
if (mTextureView != null) {
mCameraView.setFoucsPoint(new PointF(rawX, rawY));
}
}
});
/*
*點選預覽圖聚焦
*/
mCameraView.setOnViewTouchListener(new CameraView.OnViewTouchListener() {
@Override
public void handleFocus(float x, float y) {
cameraManager.handleFocusMetering(x, y);
}
@Override
public void handleZoom(boolean zoom) {
cameraManager.handleZoom(zoom);
}
});
}
/**
* 設定閃光狀態
*/
private void setCameraFlashState() {
int flashState = cameraManager.getCameraFlash();
switch (flashState) {
case 0: //自動
tv_flash.setSelected(true);
tv_flash.setText("自動");
break;
case 1://open
tv_flash.setSelected(true);
tv_flash.setText("開啟");
break;
case 2: //close
tv_flash.setSelected(false);
tv_flash.setText("關閉");
break;
}
}
/**
* 是否顯示錄製按鈕
* @param isShow
*/
private void setTakeButtonShow(boolean isShow) {
if (isShow) {
mProgressbar.setVisibility(View.VISIBLE);
rl_camera.setVisibility(cameraManager.isSupportFlashCamera()
|| cameraManager.isSupportFrontCamera() ? View.VISIBLE : View.GONE);
} else {
mProgressbar.setVisibility(View.GONE);
rl_camera.setVisibility(View.GONE);
}
}
/**
* 停止拍攝
*/
private void stopRecorder(boolean play) {
isRecording = false;
cameraManager.stopMediaRecord();
recordSecond = mProgressbar.getProgress() * PLUSH_PROGRESS;//錄製多少毫秒
mProgressbar.reset();
if (recordSecond < MIN_RECORD_TIME) {//小於最小錄製時間作廢
if (recorderPath != null) {
FileUtils.delteFiles(new File(recorderPath));
recorderPath = null;
recordSecond = 0;
}
setTakeButtonShow(true);
} else if (play && mTextureView != null && mTextureView.isAvailable()){
setTakeButtonShow(false);
mProgressbar.setVisibility(View.GONE);
iv_choice.setVisibility(View.VISIBLE);
cancel.setVisibility(View.VISIBLE);
iv_close.setVisibility(View.GONE);
cameraManager.closeCamera();
playerManager.playMedia(new Surface(mTextureView.getSurfaceTexture()), recorderPath);
}
}
@Override
protected void onResume() {
super.onResume();
if (mTextureView.isAvailable()) {
if (recorderPath != null) {//優先播放視訊
iv_choice.setVisibility(View.VISIBLE);
setTakeButtonShow(false);
playerManager.playMedia(new Surface(mTextureView.getSurfaceTexture()), recorderPath);
} else {
iv_choice.setVisibility(View.GONE);
setTakeButtonShow(true);
cameraManager.openCamera(mTextureView.getSurfaceTexture(),
mTextureView.getWidth(), mTextureView.getHeight());
}
} else {
mTextureView.setSurfaceTextureListener(listener);
}
}
@Override
protected void onPause() {
if (progressSubscription != null) {
progressSubscription.unsubscribe();
}
if (takePhotoSubscription != null) {
takePhotoSubscription.unsubscribe();
}
if (isRecording) {
stopRecorder(false);
}
cameraManager.closeCamera();
playerManager.stopMedia();
super.onPause();
}
@Override
protected void onDestroy() {
mCameraView.removeOnZoomListener();
super.onDestroy();
}
@Override
public void onClick(View v) {
int i = v.getId();
if (i == R.id.iv_close) {
// if (recorderPath != null) {//有拍攝好的正在播放,重新拍攝
// FileUtils.delteFiles(new File(recorderPath));
// recorderPath = null;
// recordSecond = 0;
// playerManager.stopMedia();
// setTakeButtonShow(true);
// iv_choice.setVisibility(View.GONE);
// cameraManager.openCamera(mTextureView.getSurfaceTexture(), mTextureView.getWidth(), mTextureView.getHeight());
// } else if (isPhotoTakingState) {
// isPhotoTakingState = false;
// iv_choice.setVisibility(View.GONE);
// setTakeButtonShow(true);
// cameraManager.restartPreview();
// } else {
finish();
// }
} else if (i == R.id.iv_choice) {//拿到圖片或視訊路徑
Intent intent=new Intent();
if(isSupportRecord){
intent.putExtra("videopath", recorderPath);
setResult(3, intent);
finish();
}else{
intent.putExtra("videopath", photoPath);
setResult(3, intent);
finish();
}
} else if (i == R.id.tv_flash) {
cameraManager.changeCameraFlash(mTextureView.getSurfaceTexture(),
mTextureView.getWidth(), mTextureView.getHeight());
setCameraFlashState();
} else if (i == R.id.iv_facing) {
cameraManager.changeCameraFacing(mTextureView.getSurfaceTexture(),
mTextureView.getWidth(), mTextureView.getHeight());
}else if(i == R.id.cancel){
if (recorderPath != null) {//有拍攝好的正在播放,重新拍攝
FileUtils.delteFiles(new File(recorderPath));
recorderPath = null;
recordSecond = 0;
playerManager.stopMedia();
setTakeButtonShow(true);
iv_choice.setVisibility(View.GONE);
cancel.setVisibility(View.GONE);
iv_close.setVisibility(View.VISIBLE);
cameraManager.openCamera(mTextureView.getSurfaceTexture(), mTextureView.getWidth(), mTextureView.getHeight());
} else if (isPhotoTakingState) {
isPhotoTakingState = false;
iv_choice.setVisibility(View.GONE);
cancel.setVisibility(View.GONE);
iv_close.setVisibility(View.VISIBLE);
setTakeButtonShow(true);
cameraManager.restartPreview();
}
}
}
/**
* camera回撥監聽
*/
private TextureView.SurfaceTextureListener listener = new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
if (recorderPath != null) {
iv_choice.setVisibility(View.VISIBLE);
setTakeButtonShow(false);
playerManager.playMedia(new Surface(texture), recorderPath);
} else {
setTakeButtonShow(true);
iv_choice.setVisibility(View.GONE);
cameraManager.openCamera(texture, width, height);
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
return true;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
}
};
private Camera.PictureCallback callback = new Camera.PictureCallback() {
@Override
public void onPictureTaken(final byte[] data, Camera camera) {
setTakeButtonShow(false);
takePhotoSubscription = Observable.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
if (!subscriber.isUnsubscribed()) {
photoPath = FileUtils.getUploadPhotoFile(mContext);
isPhotoTakingState = FileUtils.savePhoto(photoPath, data, cameraManager.isCameraFrontFacing());
subscriber.onNext(isPhotoTakingState);
}
}
}).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Subscriber<Boolean>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Boolean aBoolean) {
if (aBoolean != null && aBoolean) {
iv_choice.setVisibility(View.VISIBLE);
cancel.setVisibility(View.VISIBLE);
iv_close.setVisibility(View.GONE);
} else {
setTakeButtonShow(true);
}
}
});
}
};
}
相機管理類:
package com.ses.im.app.chat.newcamera;
import android.app.Application;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.SurfaceTexture;
import android.hardware.Camera;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.util.Log;
import android.widget.Toast;
import com.ses.im.app.chat.util.AppConfig;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
*
* 相機管理類
*/
public final class CameraManager {
private Application context;
/**
* camera
*/
private Camera mCamera;
private Camera.Parameters mParameters;
/**
* 視訊錄製
*/
private MediaRecorder mMediaRecorder;
/**
* 相機閃光狀態
*/
private int cameraFlash;
/**
* 前後置狀態
*/
private int cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
/**
* 是否支援前置攝像,是否支援閃光
*/
private boolean isSupportFrontCamera, isSupportFlashCamera;
/**
* 錄製視訊的相關引數
*/
private CamcorderProfile mProfile;
/**
* 0為拍照, 1為錄影
*/
private int cameraType;
private CameraManager(Application context) {
this.context = context;
isSupportFrontCamera = CameraUtils.isSupportFrontCamera();
isSupportFlashCamera = CameraUtils.isSupportFlashCamera(context);
if (isSupportFrontCamera) {
cameraFacing = CameraUtils.getCameraFacing(context, Camera.CameraInfo.CAMERA_FACING_BACK);
}
if (isSupportFlashCamera) {
cameraFlash = CameraUtils.getCameraFlash(context);
}
}
private static CameraManager INSTANCE;
public static CameraManager getInstance(Application context) {
if (INSTANCE == null) {
synchronized (CameraManager.class) {
if (INSTANCE == null) {
INSTANCE = new CameraManager(context);
}
}
}
return INSTANCE;
}
/**
* 開啟camera
*/
public void openCamera(SurfaceTexture surfaceTexture, int width, int height) {
if (mCamera == null) {
mCamera = Camera.open(cameraFacing);//開啟當前選中的攝像頭
mProfile = CamcorderProfile.get(cameraFacing, CamcorderProfile.QUALITY_HIGH);
try {
mCamera.setDisplayOrientation(90);//預設豎直拍照
mCamera.setPreviewTexture(surfaceTexture);
initCameraParameters(cameraFacing, width, height);
mCamera.startPreview();
} catch (Exception e) {
LogUtils.i(e);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
}
/**
* 開啟預覽,前提是camera初始化了
*/
public void restartPreview() {
if (mCamera == null) return;
try {
Camera.Parameters parameters = mCamera.getParameters();
int zoom = parameters.getZoom();
if (zoom > 0) {
parameters.setZoom(0);
mCamera.setParameters(parameters);
}
mCamera.startPreview();
} catch (Exception e) {
LogUtils.i(e);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
private void initCameraParameters(int cameraId, int width, int height) {
Camera.Parameters parameters = mCamera.getParameters();
if (cameraId == Camera.CameraInfo.CAMERA_FACING_BACK) {
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes != null) {
if (cameraType == 0) {
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
} else {
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
}
}
}
parameters.setRotation(90);//設定旋轉程式碼,
switch (cameraFlash) {
case 0:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
break;
case 1:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
break;
case 2:
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
break;
}
List<Camera.Size> pictureSizes = parameters.getSupportedPictureSizes();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
if (!isEmpty(pictureSizes) && !isEmpty(previewSizes)) {
/*for (Camera.Size size : pictureSizes) {
LogUtils.i("pictureSize " + size.width + " " + size.height);
}
for (Camera.Size size : pictureSizes) {
LogUtils.i("previewSize " + size.width + " " + size.height);
}*/
Camera.Size optimalPicSize = getOptimalCameraSize(pictureSizes, width, height);
Camera.Size optimalPreSize = getOptimalCameraSize(previewSizes, width, height);
// Camera.Size optimalPicSize = getOptimalSize(pictureSizes, width, height);
// Camera.Size optimalPreSize = getOptimalSize(previewSizes, width, height);
LogUtils.i("TextureSize "+width+" "+height+" optimalSize pic " + optimalPicSize.width + " " + optimalPicSize.height + " pre " + optimalPreSize.width + " " + optimalPreSize.height);
parameters.setPictureSize(optimalPicSize.width, optimalPicSize.height);
parameters.setPreviewSize(optimalPreSize.width, optimalPreSize.height);
mProfile.videoFrameWidth = optimalPreSize.width;
mProfile.videoFrameHeight = optimalPreSize.height;
mProfile.videoBitRate = 5000000;//此引數主要決定視訊拍出大小
}
mCamera.setParameters(parameters);
}
/**
* 釋放攝像頭
*/
public void closeCamera() {
this.cameraType = 0;
if (mCamera != null) {
try {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
} catch (Exception e) {
LogUtils.i(e);
if (mCamera != null) {
mCamera.release();
mCamera = null;
}
}
}
}
/**
* 集合不為空
*
* @param list
* @param <E>
* @return
*/
private <E> boolean isEmpty(List<E> list) {
return list == null || list.isEmpty();
}
/**
*
* @param sizes 相機support引數
* @param w
* @param h
* @return 最佳Camera size
*/
private Camera.Size getOptimalCameraSize(List<Camera.Size> sizes, int w, int h){
sortCameraSize(sizes);
int position = binarySearch(sizes, w*h);
return sizes.get(position);
}
/**
*
* @param sizes
* @param targetNum 要比較的數
* @return
*/
private int binarySearch(List<Camera.Size> sizes,int targetNum){
int targetIndex;
int left = 0,right;
int length = sizes.size();
for (right = length-1;left != right;){
int midIndex = (right + left)/2;
int mid = right - left;
Camera.Size size = sizes.get(midIndex);
int midValue = size.width * size.height;
if (targetNum == midValue){
return midIndex;
}
if (targetNum > midValue){
left = midIndex;
}else {
right = midIndex;
}
if (mid <= 1){
break;
}
}
Camera.Size rightSize = sizes.get(right);
Camera.Size leftSize = sizes.get(left);
int rightNum = rightSize.width * rightSize.height;
int leftNum = leftSize.width * leftSize.height;
targetIndex = Math.abs((rightNum - leftNum)/2) > Math.abs(rightNum - targetNum) ? right : left;
return targetIndex;
}
/**
* 排序
* @param previewSizes
*/
private void sortCameraSize(List<Camera.Size> previewSizes){
Collections.sort(previewSizes, new Comparator<Camera.Size>() {
@Override
public int compare(Camera.Size size1, Camera.Size size2) {
int compareHeight = size1.height - size2.height;
if (compareHeight == 0){
return (size1.width == size2.width ? 0 :(size1.width > size2.width ? 1:-1));
}
return compareHeight;
}
});
}
/**
* 獲取最佳預覽相機Size引數
*
* @return
*/
private Camera.Size getOptimalSize(List<Camera.Size> sizes, int w, int h) {
Camera.Size optimalSize = null;
float targetRadio = h / (float) w;
float optimalDif = Float.MAX_VALUE; //最匹配的比例
int optimalMaxDif = Integer.MAX_VALUE;//最優的最大值差距
for (Camera.Size size : sizes) {
float newOptimal = size.width / (float) size.height;
float newDiff = Math.abs(newOptimal - targetRadio);
if (newDiff < optimalDif) { //更好的尺寸
optimalDif = newDiff;
optimalSize = size;
optimalMaxDif = Math.abs(h - size.width);
} else if (newDiff == optimalDif) {//更好的尺寸
int newOptimalMaxDif = Math.abs(h - size.width);
if (newOptimalMaxDif < optimalMaxDif) {
optimalDif = newDiff;
optimalSize = size;
optimalMaxDif = newOptimalMaxDif;
}
}
}
return optimalSize;
}
/**
* 縮放
* @param isZoomIn
*/
public void handleZoom(boolean isZoomIn) {
if (mCamera == null) return;
Camera.Parameters params = mCamera.getParameters();
if (params == null) return;
if (params.isZoomSupported()) {
int maxZoom = params.getMaxZoom();
int zoom = params.getZoom();
if (isZoomIn && zoom < maxZoom) {
zoom++;
} else if (zoom > 0) {
zoom--;
}
params.setZoom(zoom);
mCamera.setParameters(params);
} else {
LogUtils.i("zoom not supported");
}
}
/**
* 更換前後置攝像
*/
public void changeCameraFacing(SurfaceTexture surfaceTexture, int width, int height) {
if(isSupportFrontCamera) {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
int cameraCount = Camera.getNumberOfCameras();//得到攝像頭的個數
for(int i = 0; i < cameraCount; i++) {
Camera.getCameraInfo(i, cameraInfo);//得到每一個攝像頭的資訊
if(cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT) { //現在是後置,變更為前置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表攝像頭的方位為前置
closeCamera();
cameraFacing = Camera.CameraInfo.CAMERA_FACING_BACK;
CameraUtils.setCameraFacing(context, cameraFacing);
openCamera(surfaceTexture, width, height);
break;
}
} else {//現在是前置, 變更為後置
if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表攝像頭的方位
closeCamera();
cameraFacing = Camera.CameraInfo.CAMERA_FACING_FRONT;
CameraUtils.setCameraFacing(context, cameraFacing);
openCamera(surfaceTexture, width, height);
break;
}
}
}
} else { //不支援攝像機
Toast.makeText(context, "您的手機不支援前置攝像", Toast.LENGTH_SHORT).show();
}
}
/**
* 改變閃光狀態
*/
public void changeCameraFlash(SurfaceTexture surfaceTexture, int width, int height) {
if (!isSupportFlashCamera) {
Toast.makeText(context, "您的手機不支閃光", Toast.LENGTH_SHORT).show();
return;
}
if(mCamera != null) {
Camera.Parameters parameters = mCamera.getParameters();
if(parameters != null) {
int newState = cameraFlash;
switch (cameraFlash) {
case 0: //自動
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
newState = 1;
break;
case 1://open
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
newState = 2;
break;
case 2: //close
parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
newState = 0;
break;
}
cameraFlash = newState;
CameraUtils.setCameraFlash(context, newState);
mCamera.setParameters(parameters);
}
}
}
/**
* 拍照
*/
public void takePhoto(Camera.PictureCallback callback) {
if (mCamera != null) {
try {
mCamera.takePicture(null, null, callback);
} catch(Exception e) {
Toast.makeText(context, "拍攝失敗", Toast.LENGTH_SHORT).show();
}
}
}
/**
* 開始錄製視訊
*/
// public void startMediaRecord(String savePath) {
// if (mCamera == null || mProfile == null) return;
// mCamera.unlock();
// if (mMediaRecorder == null) {
// mMediaRecorder = new MediaRecorder();
// }
// if (isCameraFrontFacing()) {
// mMediaRecorder.setOrientationHint(270);
// Log.i("wujie","front");
// }else
// {
// Log.i("wujie","back");
// mMediaRecorder.setOrientationHint(90);
// }
// mMediaRecorder.reset();
// mMediaRecorder.setCamera(mCamera);
// mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
// mMediaRecorder.setProfile(mProfile);
// mMediaRecorder.setOutputFile(savePath);
// try {
// mMediaRecorder.prepare();
// mMediaRecorder.start();
// } catch (Exception e) {
// e.printStackTrace();
//
// }
// }
/**
* 開始錄製視訊
*/
public void startMediaRecord1(String savePath) {
if (mCamera == null) {
return;
}
if (mMediaRecorder == null) {
mMediaRecorder = new MediaRecorder();
} else {
mMediaRecorder.reset();
}
if (isCameraFrontFacing()) {
mMediaRecorder.setOrientationHint(270);
Log.i("wujie","front");
}else
{
Log.i("wujie","back");
mMediaRecorder.setOrientationHint(90);
}
mParameters = mCamera.getParameters();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
// 設定錄影引數
mMediaRecorder.setProfile(CamcorderProfile.get(AppConfig.VIDEOSIZE));
try {
mMediaRecorder.setOutputFile(savePath);
mMediaRecorder.prepare();
mMediaRecorder.start();
} catch (Exception e) {
}
}
/**
* 停止錄製
*/
public void stopMediaRecord() {
this.cameraType = 0;
stopRecorder();
releaseMediaRecorder();
}
private void releaseMediaRecorder() {
if (mMediaRecorder != null) {
try {
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
mCamera.lock();
} catch (Exception e) {
e.printStackTrace();
LogUtils.i(e);
}
}
}
private void stopRecorder() {
if (mMediaRecorder != null) {
try {
mMediaRecorder.stop();
} catch (Exception e) {
e.printStackTrace();
LogUtils.i(e);
}
}
}
public boolean isSupportFrontCamera() {
return isSupportFrontCamera;
}
public boolean isSupportFlashCamera() {
return isSupportFlashCamera;
}
public boolean isCameraFrontFacing() {
return cameraFacing == Camera.CameraInfo.CAMERA_FACING_FRONT;
}
/**
* 設定對焦型別
* @param cameraType
*/
public void setCameraType(int cameraType) {
this.cameraType = cameraType;
if (mCamera != null) {//拍攝視訊時
if (cameraFacing == Camera.CameraInfo.CAMERA_FACING_BACK) {
Camera.Parameters parameters = mCamera.getParameters();
List<String> focusModes = parameters.getSupportedFocusModes();
if (focusModes != null) {
if (cameraType == 0) {
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
}
} else {
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
}
}
}
}
}
}
public int getCameraFlash() {
return cameraFlash;
}
/**
* 對焦
* @param x
* @param y
*/
public void handleFocusMetering(float x, float y) {
if(mCamera!=null){
Camera.Parameters params = mCamera.getParameters();
Camera.Size previewSize = params.getPreviewSize();
Rect focusRect = calculateTapArea(x, y, 1f, previewSize);
Rect meteringRect = calculateTapArea(x, y, 1.5f, previewSize);
mCamera.cancelAutoFocus();
if (params.getMaxNumFocusAreas() > 0) {
List<Camera.Area> focusAreas = new ArrayList<>();
focusAreas.add(new Camera.Area(focusRect, 1000));
params.setFocusAreas(focusAreas);
} else {
LogUtils.i("focus areas not supported");
}
if (params.getMaxNumMeteringAreas() > 0) {
List<Camera.Area> meteringAreas = new ArrayList<>();