国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Android > 正文

Android仿最新微信相機功能

2019-10-22 18:10:23
字體:
來源:轉載
供稿:網友

最近在開發即時通訊這個模塊的時候使用到了自定義的相機,需求與微信一樣,要求相機能長按和輕點,當時在網上找自定義相機的資源,很少,所以,我在這里把我的一些開發經驗貼出來,供大家學習。

大致完成的功能如下:

  • 長按拍攝視頻,輕點拍照
  • 前后攝像頭的切換
  • 閃光的的開啟,關閉,自動
  • 圖片的壓縮
  • 自動聚焦,手動聚焦

效果圖如下: 

Android,微信相機

相關代碼如下:

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<>();    meteringAreas.add(new Camera.Area(meteringRect, 1000));    params.setMeteringAreas(meteringAreas);   } else {    LogUtils.i("metering areas not supported");   }   final String currentFocusMode = params.getFocusMode();   params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);   mCamera.setParameters(params);   mCamera.autoFocus(new Camera.AutoFocusCallback() {    @Override    public void onAutoFocus(boolean success, Camera camera) {     Camera.Parameters params = camera.getParameters();     params.setFocusMode(currentFocusMode);     camera.setParameters(params);    }   });  } } private Rect calculateTapArea(float x, float y, float coefficient, Camera.Size previewSize) {  float focusAreaSize = 300;  int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();  int centerX = (int) (x / previewSize.width - 1000);  int centerY = (int) (y / previewSize.height - 1000);  int left = clamp(centerX - areaSize / 2, -1000, 1000);  int top = clamp(centerY - areaSize / 2, -1000, 1000);  RectF rectF = new RectF(left, top, left + areaSize, top + areaSize);  return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom)); } private int clamp(int x, int min, int max) {  if (x > max) {   return max;  }  if (x < min) {   return min;  }  return x; }}

自定義拍攝,拍照按鈕:

package com.ses.im.app.chat.newcamera;import android.content.Context;import android.content.res.TypedArray;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.RectF;import android.os.Bundle;import android.os.Parcelable;import android.support.v4.view.GestureDetectorCompat;import android.support.v4.view.MotionEventCompat;import android.util.AttributeSet;import android.view.GestureDetector;import android.view.MotionEvent;import android.view.View;import android.view.ViewConfiguration;import com.ses.im.app.chat.R;/** * 自定義拍照,拍攝按鈕 */public class CameraProgressBar extends View { /**  * 默認縮小值  */ public static final float DEF_SCALE = 0.75F; /**  * 默認縮小值  */ private float scale = DEF_SCALE; /**  * 內圓顏色  */ private int innerColor = Color.GRAY; /**  * 背景顏色  */ private int backgroundColor = Color.WHITE; /**  * 外圓顏色  */ private int outerColor = Color.parseColor("#e9e9e9"); /**  * 進度顏色  */ private int progressColor = Color.parseColor("#0ebffa"); /**  * 進度寬  */ private int progressWidth = 15; /**  * 內圓寬度  */ private int innerRadio = 10; /**  * 進度  */ private int progress; /**  * 最大進度  */ private int maxProgress = 100; /**  * paint  */ private Paint backgroundPaint, progressPaint, innerPaint; /**  * 圓的中心坐標點, 進度百分比  */ private float sweepAngle; /**  * 手識識別  */ private GestureDetectorCompat mDetector; /**  * 是否為長按錄制  */ private boolean isLongClick; /**  * 是否產生滑動  */ private boolean isBeingDrag; /**  * 滑動單位  */ private int mTouchSlop; /**  * 記錄上一次Y軸坐標點  */ private float mLastY; /**  * 是否長按放大  */ private boolean isLongScale; public CameraProgressBar(Context context) {  super(context);  init(context, null); } public CameraProgressBar(Context context, AttributeSet attrs) {  super(context, attrs);  init(context, attrs); } public CameraProgressBar(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(context, attrs); } private void init(Context context, AttributeSet attrs) {  mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();  if (attrs != null) {   TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CameraProgressBar);   innerColor = a.getColor(R.styleable.CameraProgressBar_innerColor, innerColor);   outerColor = a.getColor(R.styleable.CameraProgressBar_outerColor, outerColor);   progressColor = a.getColor(R.styleable.CameraProgressBar_progressColor, progressColor);   innerRadio = a.getDimensionPixelOffset(R.styleable.CameraProgressBar_innerRadio, innerRadio);   progressWidth = a.getDimensionPixelOffset(R.styleable.CameraProgressBar_progressWidth, progressWidth);   progress = a.getInt(R.styleable.CameraProgressBar_progresscamera, progress);   scale = a.getFloat(R.styleable.CameraProgressBar_scale, scale);   isLongScale = a.getBoolean(R.styleable.CameraProgressBar_isLongScale, isLongScale);   maxProgress = a.getInt(R.styleable.CameraProgressBar_maxProgress, maxProgress);   a.recycle();  }  backgroundPaint = new Paint();  backgroundPaint.setAntiAlias(true);  backgroundPaint.setColor(backgroundColor);  progressPaint = new Paint();  progressPaint.setAntiAlias(true);  progressPaint.setStrokeWidth(progressWidth);  progressPaint.setStyle(Paint.Style.STROKE);  innerPaint = new Paint();  innerPaint.setAntiAlias(true);  innerPaint.setStrokeWidth(innerRadio);  innerPaint.setStyle(Paint.Style.STROKE);  sweepAngle = ((float) progress / maxProgress) * 360;  mDetector = new GestureDetectorCompat(context, new GestureDetector.SimpleOnGestureListener() {   @Override   public boolean onSingleTapConfirmed(MotionEvent e) {    isLongClick = false;    if (CameraProgressBar.this.listener != null) {     CameraProgressBar.this.listener.onClick(CameraProgressBar.this);    }    return super.onSingleTapConfirmed(e);   }   @Override   public void onLongPress(MotionEvent e) {    isLongClick = true;    postInvalidate();    mLastY = e.getY();    if (CameraProgressBar.this.listener != null) {     CameraProgressBar.this.listener.onLongClick(CameraProgressBar.this);    }   }  });  mDetector.setIsLongpressEnabled(true); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  super.onMeasure(widthMeasureSpec, heightMeasureSpec);  int width = MeasureSpec.getSize(widthMeasureSpec);  int height = MeasureSpec.getSize(heightMeasureSpec);  if (width > height) {   setMeasuredDimension(height, height);  } else {   setMeasuredDimension(width, width);  } } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  int width = getWidth();  float circle = width / 2.0f;  if (/*isLongScale && */!isLongClick) {   canvas.scale(scale, scale, circle, circle);  }  //畫內圓  float backgroundRadio = circle - progressWidth - innerRadio;  canvas.drawCircle(circle, circle, backgroundRadio, backgroundPaint);  //畫內外環  float halfInnerWidth = innerRadio / 2.0f + progressWidth;  RectF innerRectF = new RectF(halfInnerWidth, halfInnerWidth, width - halfInnerWidth, width - halfInnerWidth);  canvas.drawArc(innerRectF, -90, 360, true, innerPaint);  progressPaint.setColor(outerColor);  float halfOuterWidth = progressWidth / 2.0f;  RectF outerRectF = new RectF(halfOuterWidth, halfOuterWidth, getWidth() - halfOuterWidth, getWidth() - halfOuterWidth);  canvas.drawArc(outerRectF, -90, 360, true, progressPaint);  progressPaint.setColor(progressColor);  canvas.drawArc(outerRectF, -90, sweepAngle, false, progressPaint); } @Override public boolean onTouchEvent(MotionEvent event) {  if (!isLongScale) {   return super.onTouchEvent(event);  }  this.mDetector.onTouchEvent(event);  switch(MotionEventCompat.getActionMasked(event)) {   case MotionEvent.ACTION_DOWN:    isLongClick = false;    isBeingDrag = false;    break;   case MotionEvent.ACTION_MOVE:    if (isLongClick) {     float y = event.getY();     if (isBeingDrag) {      boolean isUpScroll = y < mLastY;      mLastY = y;      if (this.listener != null) {       this.listener.onZoom(isUpScroll);      }     } else {      isBeingDrag = Math.abs(y - mLastY) > mTouchSlop;     }    }    break;   case MotionEvent.ACTION_UP:   case MotionEvent.ACTION_CANCEL:    isBeingDrag = false;    if (isLongClick) {     isLongClick = false;     postInvalidate();     if (this.listener != null) {      this.listener.onLongClickUp(this);     }    }    break;   case MotionEvent.ACTION_POINTER_DOWN:    if (isLongClick) {     if (this.listener != null) {      this.listener.onPointerDown(event.getRawX(), event.getRawY());     }    }    break;  }  return true; } @Override protected Parcelable onSaveInstanceState() {  Bundle bundle = new Bundle();  Parcelable superData = super.onSaveInstanceState();  bundle.putParcelable("superData", superData);  bundle.putInt("progress", progress);  bundle.putInt("maxProgress", maxProgress);  return bundle; } @Override protected void onRestoreInstanceState(Parcelable state) {  Bundle bundle = (Bundle) state;  Parcelable superData = bundle.getParcelable("superData");  progress = bundle.getInt("progress");  maxProgress = bundle.getInt("maxProgress");  super.onRestoreInstanceState(superData); } /**  * 設置進度  * @param progress  */ public void setProgress(int progress) {  if (progress <= 0) progress = 0;  if (progress >= maxProgress) progress = maxProgress;  if (progress == this.progress) return;  this.progress = progress;  this.sweepAngle = ((float) progress / maxProgress) * 360;  postInvalidate(); } /**  * 還原到初始狀態  */ public void reset() {  isLongClick = false;  this.progress = 0;  this.sweepAngle = 0;  postInvalidate(); } public int getProgress() {  return progress; } public void setLongScale(boolean longScale) {  isLongScale = longScale; } public void setMaxProgress(int maxProgress) {  this.maxProgress = maxProgress; } private OnProgressTouchListener listener; public void setOnProgressTouchListener(OnProgressTouchListener listener) {  this.listener = listener; } /**  * 進度觸摸監聽  */ public interface OnProgressTouchListener {  /**   * 單擊   * @param progressBar   */  void onClick(CameraProgressBar progressBar);  /**   * 長按   * @param progressBar   */  void onLongClick(CameraProgressBar progressBar);  /**   * 移動   * @param zoom true放大   */  void onZoom(boolean zoom);  /**   * 長按抬起   * @param progressBar   */  void onLongClickUp(CameraProgressBar progressBar);  /**   * 觸摸對焦   * @param rawX   * @param rawY   */  void onPointerDown(float rawX, float rawY); }}

預覽試圖頁:

package com.ses.im.app.chat.newcamera;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.graphics.PointF;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.RectF;import android.support.v4.view.MotionEventCompat;import android.util.AttributeSet;import android.view.MotionEvent;import android.view.View;import android.view.ViewParent;import java.util.concurrent.TimeUnit;import rx.Observable;import rx.Subscriber;import rx.Subscription;/** * 相機預覽頁 */public class CameraView extends View { /**  * 動畫時長  */ private static final int ANIM_MILS = 600; /**  * 動畫每多久刷新一次  */ private static final int ANIM_UPDATE = 30; /**  * focus paint  */ private Paint paint, clearPaint; private int paintColor = Color.GREEN; /**  * 進度訂閱  */ private Subscription subscription; /**  * focus rectf  */ private RectF rectF = new RectF(); /**  * focus size  */ private int focusSize = 120; private int lineSize = focusSize / 4; /**  * 上一次兩指距離  */ private float oldDist = 1f; /**  * 畫筆寬  */ private float paintWidth = 6.0f; /**  * s  */ private float scale; public CameraView(Context context) {  super(context);  init(); } public CameraView(Context context, AttributeSet attrs) {  super(context, attrs);  init(); } public CameraView(Context context, AttributeSet attrs, int defStyleAttr) {  super(context, attrs, defStyleAttr);  init(); } private void init() {  paint = new Paint();  paint.setColor(paintColor);  paint.setStyle(Paint.Style.STROKE);  paint.setStrokeWidth(paintWidth);  clearPaint = new Paint();  clearPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR)); } @Override public boolean onTouchEvent(MotionEvent event) {  int action = MotionEventCompat.getActionMasked(event);  if (event.getPointerCount() == 1 && action == MotionEvent.ACTION_DOWN) {   float x = event.getX();   float y = event.getY();   setFoucsPoint(x, y);   if (listener != null) {    listener.handleFocus(x, y);   }  } else if (event.getPointerCount() >= 2){   switch (event.getAction() & MotionEvent.ACTION_MASK) {    case MotionEvent.ACTION_POINTER_DOWN:     oldDist = getFingerSpacing(event);     break;    case MotionEvent.ACTION_MOVE:     float newDist = getFingerSpacing(event);     if (newDist > oldDist) {      if (this.listener != null) {       this.listener.handleZoom(true);      }     } else if (newDist < oldDist) {      if (this.listener != null) {       this.listener.handleZoom(false);      }     }     oldDist = newDist;     break;   }  }  return true; } /**  * 計算兩點觸控距離  * @param event  * @return  */ private float getFingerSpacing(MotionEvent event) {  float x = event.getX(0) - event.getX(1);  float y = event.getY(0) - event.getY(1);  return (float) Math.sqrt(x * x + y * y); } /**  * 設置坐標點(坐標為rawX, rawY)  */ public void setFoucsPoint(PointF pointF) {  PointF transPointF = transPointF(pointF, this);  setFoucsPoint(transPointF.x, transPointF.y); } /**  * 設置當前觸摸點  * @param x  * @param y  */ private void setFoucsPoint(float x, float y) {  if (subscription != null) {   subscription.unsubscribe();  }  rectF.set(x - focusSize, y - focusSize, x + focusSize, y + focusSize);  final int count = ANIM_MILS / ANIM_UPDATE;  subscription = Observable.interval(ANIM_UPDATE, TimeUnit.MILLISECONDS).take(count).subscribe(new Subscriber<Long>() {   @Override   public void onCompleted() {    scale = 0;    postInvalidate();   }   @Override   public void onError(Throwable e) {    scale = 0;    postInvalidate();   }   @Override   public void onNext(Long aLong) {    float current = aLong== null ? 0 : aLong.longValue();    scale = 1 - current / count;    if (scale <= 0.5f) {     scale = 0.5f;    }    postInvalidate();   }  }); } @Override protected void onDraw(Canvas canvas) {  super.onDraw(canvas);  if (scale != 0) {   float centerX = rectF.centerX();   float centerY = rectF.centerY();   canvas.scale(scale, scale, centerX, centerY);   canvas.drawRect(rectF, paint);   canvas.drawLine(rectF.left, centerY, rectF.left + lineSize, centerY, paint);   canvas.drawLine(rectF.right, centerY, rectF.right - lineSize, centerY, paint);   canvas.drawLine(centerX, rectF.top, centerX, rectF.top + lineSize, paint);   canvas.drawLine(centerX, rectF.bottom, centerX, rectF.bottom - lineSize, paint);  } } @Override protected void onDetachedFromWindow() {  super.onDetachedFromWindow();  if (subscription != null) {   subscription.unsubscribe();  } } /**  * 根據raw坐標轉換成屏幕中所在的坐標  * @param pointF  * @return  */ private PointF transPointF(PointF pointF, View view) {  pointF.x -= view.getX();  pointF.y -= view.getY();  ViewParent parent = view.getParent();  if (parent instanceof View) {   return transPointF(pointF, (View) parent);  } else {   return pointF;  } } private OnViewTouchListener listener; public void setOnViewTouchListener(OnViewTouchListener listener) {  this.listener = listener; } public void removeOnZoomListener() {  this.listener = null; } public interface OnViewTouchListener {  /**   * 對焦   * @param x   * @param y   */  void handleFocus(float x, float y);  /**   * 縮放   * @param zoom true放大反之   */  void handleZoom(boolean zoom); }}

視頻管理類:

package com.ses.im.app.chat.newcamera;import android.app.Application; import android.media.MediaPlayer; import android.view.Surface;/** * Created by you on 2016/10/24. * 由于拍攝跟播放都關聯TextureView,停止播放時要釋放mediaplayer */public class MediaPlayerManager {private Application app;private MediaPlayer mPlayer;private MediaPlayerManager(Application app) { this.app = app;}private static MediaPlayerManager INSTANCE;public static MediaPlayerManager getInstance(Application app) { if (INSTANCE == null) {  synchronized (CameraManager.class) {   if (INSTANCE == null) {    INSTANCE = new MediaPlayerManager(app);   }  } } return INSTANCE;}/** * 播放Media */public void playMedia(Surface surface, String mediaPath) { try {  if (mPlayer == null) {   mPlayer = new MediaPlayer();   mPlayer.setDataSource(mediaPath);  } else {   if (mPlayer.isPlaying()) {    mPlayer.stop();   }   mPlayer.reset();   mPlayer.setDataSource(mediaPath);  }  mPlayer.setSurface(surface);  mPlayer.setLooping(true);  mPlayer.prepareAsync();  mPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {   @Override   public void onPrepared(MediaPlayer mp) {    mp.start();   }  }); } catch (Exception e) {  LogUtils.i(e); }}/** * 停止播放Media */public void stopMedia() { try {  if (mPlayer != null) {   if (mPlayer.isPlaying()) {    mPlayer.stop();   }   mPlayer.release();   mPlayer = null;  } } catch (Exception e) {  LogUtils.i(e); }}}

由于本人上傳的demo被csdn弄丟了,想要做微信相機的可以參考陳嘉桐的demo

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VEVB武林網。


注:相關教程知識閱讀請移步到Android開發頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 桂阳县| 绵竹市| 湄潭县| 九寨沟县| 顺义区| 十堰市| 永寿县| 绥芬河市| 永善县| 高阳县| 阜南县| 永昌县| 宣恩县| 六盘水市| 敦煌市| 舒兰市| 宁南县| 佳木斯市| 乌兰浩特市| 新津县| 抚宁县| 鞍山市| 哈尔滨市| 兴安县| 寿宁县| 保定市| 连云港市| 正蓝旗| 济阳县| 绥芬河市| 古交市| 鄂伦春自治旗| 理塘县| 白水县| 乌拉特中旗| 西峡县| 闽侯县| 白朗县| 绥阳县| 罗甸县| 五华县|