首页 > 系统 > Android > 正文

android 7自定义相机预览及拍照功能

2019-10-22 18:10:25
字体:
来源:转载
供稿:网友

本文实例为大家分享了Android实现摄像头切换,拍照及保存到相册,预览等功能,解决android7拍照之后不能连续预览的问题、参数设置相关问题以及前后摄像头语言颠倒等问题。

import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.hardware.Camera; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.support.v4.app.ActivityCompat; import android.util.Log; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.WindowManager; import android.widget.TextView;  import com.hama.tracker.R;  import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List;   public class CamaraActivity extends Activity implements View.OnClickListener {   @Bind(R.id.return_back)  TextView returnBack;  @Bind(R.id.tvswitch_camera)  TextView tvswitchCamera;  //启动摄像机  private Camera mCamera;   public boolean isopen_camara = false;  private SurfaceView surfaceView;  private SurfaceHolder mholder = null;  private SurfaceCallback previewCallBack;  private boolean isTakingPhoto;//是否正在拍照   @Override  protected void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   verifyPermission(new String[]{Manifest.permission.CAMERA});   // getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);   setContentView(R.layout.activity_camara);   ButterKnife.bind(this);    // 预览控件   surfaceView = (SurfaceView) this     .findViewById(R.id.surfaceView);   // 设置参数   surfaceView.getHolder().setKeepScreenOn(true);   surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    returnBack.setOnClickListener(this);   tvswitchCamera.setOnClickListener(this);   EventBus.getDefault().register(this);  }   public void verifyPermission(String[] permissions) {   if (permissions != null) {    List<String> lists = new ArrayList<>();    for (int i = 0; i < permissions.length; i++) {     if (ActivityCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {      if (ActivityCompat.shouldShowRequestPermissionRationale(this, permissions[i])) {       }      lists.add(permissions[i]);     }    }    if (lists.size() > 0) {     String[] ps = new String[lists.size()];     for (int i = 0; i < lists.size(); i++) {      ps[i] = lists.get(i);     }     ActivityCompat.requestPermissions(this, ps, 1);    }   }  }   @Override  protected void onRestart() {   super.onRestart();  }   @Override  protected void onStart() {   super.onStart();  }   private void takePhoto() {   if (!isopen_camara) {    previewCallBack = new SurfaceCallback();    surfaceView.getHolder().addCallback(previewCallBack);   } else {    autoTakePhoto();   }  }    @Override  protected void onResume() {   super.onResume();   if(mCamera == null){    if (!isopen_camara) {     previewCallBack = new SurfaceCallback();     surfaceView.getHolder().addCallback(previewCallBack);    }   }   }   @Override  public void onClick(View v) {   switch (v.getId()) {    case R.id.return_back:     finish();     break;    case R.id.tvswitch_camera:     switchCamara();     break;   }  }    // 预览界面回调  private final class SurfaceCallback implements SurfaceHolder.Callback {   // 预览界面被创建   public void surfaceCreated(SurfaceHolder holder) {    try {     //1代表打开后置摄像头,0代表打开前置摄像头.     mCamera = Camera.open(cameraPosition);// 打开摄像头     setParams(holder,cameraPosition);    } catch (Exception e) {     e.printStackTrace();     if (mCamera != null) {      mCamera.stopPreview();      mCamera.lock();      mCamera.release();      mCamera = null;     }     finish();     //Toast.makeText(getApplicationContext(), "该手机不支持自动拍照功能", Toast.LENGTH_LONG).show();    }   }    public void surfaceChanged(SurfaceHolder holder, int format, int width,          int height) {    System.out.println("surfaceChanged");    isopen_camara = true;    //autoTakePhoto();   }    // 预览界面被销毁   public void surfaceDestroyed(SurfaceHolder holder) {    System.out.println("surfaceDestroyed");    if(!isopen_camara)     return;    if (mCamera != null) {     holder.removeCallback(this);     mCamera.setPreviewCallback(null);     mCamera.stopPreview();     mCamera.lock();     mCamera.release();     mCamera = null;    }   }   }   public void reset(){   Camera.CameraInfo cameraInfo = new Camera.CameraInfo();   if (mCamera != null) {    if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){     surfaceView.getHolder().removeCallback(previewCallBack);    }    mCamera.setPreviewCallback(null);    mCamera.stopPreview();    mCamera.lock();    mCamera.release();    mCamera = null;     mCamera = Camera.open(cameraPosition);    if (null != mholder)     setParams(mholder,cameraInfo.facing);   }   }   @Override  protected void onDestroy() {   super.onDestroy();   if (mCamera != null) {    if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){     surfaceView.getHolder().removeCallback(previewCallBack);    }    mCamera.setPreviewCallback(null);    mCamera.stopPreview();    mCamera.lock();    mCamera.release();    mCamera = null;   }   ButterKnife.unbind(this);   EventBus.getDefault().unregister(this);  }   private void setParams(SurfaceHolder mySurfaceView,int postion) {   try {    int PreviewWidth = 0;    int PreviewHeight = 0;    WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//获取窗口的管理器    /*PreviewWidth = display.();    PreviewHeight = display.getHeight();*/     Camera.Parameters parameters = mCamera.getParameters();    // 选择合适的预览尺寸    List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();     // 如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择    if (sizeList.size() > 1) {     Iterator<Camera.Size> itor = sizeList.iterator();     while (itor.hasNext()) {      Camera.Size cur = itor.next();      /*if (cur.width >= PreviewWidth        && cur.height >= PreviewHeight) {*/      if (cur.width >= PreviewWidth        && cur.height >= PreviewHeight) {       PreviewWidth = cur.width;       PreviewHeight = cur.height;       break;      }      }    }    parameters.setPreviewSize(PreviewWidth, PreviewHeight); //获得摄像区域的大小    //parameters.setPreviewFrameRate(3);//每秒3帧 每秒从摄像头里面获得3个画面    //parameters.setPreviewFpsRange(3,);    List<int[]> list = parameters.getSupportedPreviewFpsRange();    int[] v = null;    int index = 0;    int min = 0;    for (int i = 0; i < list.size(); i++) {     v = list.get(i);     if (v[0] > min) {      min = v[0];      index = i;     }    }    parameters.setPreviewFpsRange(list.get(index)[0], list.get(index)[1]);    parameters.setPictureFormat(PixelFormat.JPEG);//设置照片输出的格式    parameters.set("jpeg-quality", 85);//设置照片质量    parameters.setPictureSize(PreviewWidth, PreviewHeight);//设置拍出来的屏幕大小    parameters.setRotation(180); //Java部分    if (Build.VERSION.SDK_INT >= 24) {     if(postion == 0){      mCamera.setDisplayOrientation(90);     }else {      mCamera.setDisplayOrientation(270);     }    } else {     mCamera.setDisplayOrientation(90);    }       mCamera.setParameters(parameters);//把上面的设置 赋给摄像头    mCamera.setPreviewDisplay(mySurfaceView);//把摄像头获得画面显示在SurfaceView控件里面    mholder = mySurfaceView;    mCamera.setPreviewCallback(new Camera.PreviewCallback() {     @Override     public void onPreviewFrame(byte[] data, Camera camera) {      }    });    mCamera.startPreview();//开始预览    // mPreviewRunning = true;   } catch (IOException e) {    Log.e("tag", e.toString());   }  }   Handler handler = null;   private void autoTakePhoto() {   // 拍照前需要对焦 获取清析的图片   if (null == mCamera) return;   mCamera.autoFocus(new Camera.AutoFocusCallback() {    @Override    public void onAutoFocus(boolean success, Camera camera) {      if (success && isopen_camara) {      // 对焦成功      // Toast.makeText(MainActivity.this, "对焦成功 !!",Toast.LENGTH_SHORT).show();      if(!isTakingPhoto) {       isTakingPhoto = true;       handler = new Handler();       handler.post(new Runnable() {        @Override        public void run() {         mCamera.takePicture(null, null, new MyPictureCallback());        }       });      }     }    }   });  }   // 照片回调  private final class MyPictureCallback implements Camera.PictureCallback {   // 照片生成后   @Override   public void onPictureTaken(byte[] data, Camera camera) {    try {     Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);     Matrix matrix = new Matrix();     matrix.setRotate(270);      File jpgFile = new File(Environment.getExternalStorageDirectory() + "/DCIM/camera");     if (!jpgFile.exists()) {      jpgFile.mkdir();     }     File jpgFile1 = new File(jpgFile.getAbsoluteFile(), System.currentTimeMillis() + ".jpg");     bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);     FileOutputStream fos = new FileOutputStream(jpgFile1);     bitmap.compress(Bitmap.CompressFormat.JPEG, 80, fos);     ToastUtils.show(getApplicationContext(), getString(R.string.save_success));     fos.close();     Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);     Uri uri = Uri.fromFile(jpgFile1);     intent.setData(uri);     sendBroadcast(intent);    } catch (Exception e) {     e.printStackTrace();    }finally {     if(Build.VERSION.SDK_INT>=24){      reset();     }     isTakingPhoto = false;    }   }  }   private int cameraPosition = 1;//0代表前置摄像头,1代表后置摄像头   private void switchCamara() {   //切换前后摄像头   int cameraCount = 0;   Camera.CameraInfo cameraInfo = new Camera.CameraInfo();   cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数    for (int i = 0; i < cameraCount; i++) {    Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息    if (cameraPosition == 1) {     //现在是后置,变更为前置     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位,CAMERA_FACING_FRONT前置  CAMERA_FACING_BACK后置      if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){       surfaceView.getHolder().removeCallback(previewCallBack);      }      mCamera.setPreviewCallback(null);      mCamera.stopPreview();//停掉原来摄像头的预览      mCamera.lock();      mCamera.release();//释放资源      mCamera = null;//取消原来摄像头      mCamera = Camera.open(i);//打开当前选中的摄像头      /* try {       if (null != mholder)        mCamera.setPreviewDisplay(mholder);//通过surfaceview显示取景画面      } catch (IOException e) {       // TODO Auto-generated catch block       e.printStackTrace();      }      mCamera.startPreview();//开始预览*/      if (null != mholder)       setParams(mholder,Camera.CameraInfo.CAMERA_FACING_BACK);      cameraPosition = 0;      break;     }    } else {     //现在是前置, 变更为后置     if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位,CAMERA_FACING_FRONT前置  CAMERA_FACING_BACK后置      if(surfaceView != null && surfaceView.getHolder() != null && previewCallBack != null){       surfaceView.getHolder().removeCallback(previewCallBack);      }      mCamera.setPreviewCallback(null);      mCamera.stopPreview();//停掉原来摄像头的预览      mCamera.lock();      mCamera.release();//释放资源      mCamera = null;//取消原来摄像头      mCamera = Camera.open(i);//打开当前选中的摄像头      /*try {       if (null != mholder)        mCamera.setPreviewDisplay(mholder);//通过surfaceview显示取景画面      } catch (IOException e) {       // TODO Auto-generated catch block       e.printStackTrace();      }      mCamera.startPreview();//开始预览*/      if (null != mholder)       setParams(mholder,Camera.CameraInfo.CAMERA_FACING_FRONT);      cameraPosition = 1;      break;     }    }    }  }   @Override  public boolean onKeyDown(int keyCode, KeyEvent event) {   if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {///音量减拍照    takePhoto();    return true;   }   return super.onKeyDown(keyCode, event);   } } 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表