Android自定义Camera实现拍照小功能

Android自定义Camera实现拍照小功能

本文实例为大家分享了Android自定义Camera实现拍照的具体代码,供大家参考,具体内容如下

本篇文章就项目开发遇到问题记录下;

1.拍照图片被压缩问题
2.拍照图片被旋转问题

首先实现一个自定义拍照功能。

自定义布局

<FrameLayout         android:layout_below="@id/toolbar_layout"         android:layout_width="match_parent"         android:layout_height="match_parent" >         <SurfaceView             android:id="@+id/surface"             android:layout_width="match_parent"             android:layout_height="match_parent"             android:keepScreenOn="true"/>     </FrameLayout>

初始化控件:

surfaceView = (SurfaceView) findViewById(R.id.surface); holder = surfaceView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); btn.setOnCLickListener(new OnClickLister(View v){     if(mCamera == null){         mCamera = Camera.open();     } mCamera.takePicture(null,null,this); });  @Override public void surfaceCreated(SurfaceHolder surfaceHolder) {       initStartCamera(surfaceHolder); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {           mCamera.autoFocus(new Camera.AutoFocusCallback() {             @Override             public void onAutoFocus(boolean success, Camera camera) {                 isAutoFocus = success;                 initCameraParams();                 mCamera.cancelAutoFocus();                 mCamera.startPreview();             }         }); } @Override    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {        // 当holder被回收时 释放硬件        //   releaseCamera();    }      @Override     protected void onPause() {         super.onPause();         releaseCameraSource();     }   @Override     protected void onResume() {         super.onResume();         // TODO:  看看退出到其他页面是否有黑屏现象         if (surfaceView != null) {             surfaceView.postDelayed(new Runnable() {                 @Override                 public void run() {                     initCameraParams();                 }             }, 50);         }     }   private void initStartCamera(SurfaceHolder surfaceHolder) {         try {             mCamera = Camera.open();             mCamera.setDisplayOrientation(90);             mCamera.setPreviewDisplay(surfaceHolder);             mCamera.startPreview();         } catch (IOException e) {             e.printStackTrace();         }     } private void initCameraParams() {         if (mCamera != null) {             Camera.Parameters parameters = mCamera.getParameters();             parameters.setPictureFormat(ImageFormat.JPEG);             parameters.setJpegQuality(90);             List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();             WindowManager manager = (WindowManager) getSystemService(WINDOW_SERVICE);             Display display = manager.getDefaultDisplay();             Point point = new Point();             display.getSize(point);             int screenWidth = point.x;             int screenHeight = point.y;             // 找到适合的图片的尺寸             if (supportedPictureSizes != null && !supportedPictureSizes.isEmpty()) {                 int screenSize = screenHeight * screenWidth;                 Camera.Size picSize = null;                 for (Camera.Size size : supportedPictureSizes) {                     int value = size.height * size.width;                     if (value <= screenSize) {                         if (picSize == null) {                             picSize = size;                         } else {                             // 取最接近屏幕尺寸的                             if (value > picSize.width * picSize.height) {                                 picSize = size;                             }                         }                     }                 }                 if (picSize == null) {                     picSize = supportedPictureSizes.get(0);                 }                 parameters.setPictureSize(picSize.width, picSize.height);             }             // 设置对焦模式             List<String> supportedFocusModes = parameters.getSupportedFocusModes();             if (supportedFocusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {                 // 快速对焦                 parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);             } else {                 parameters.setFocusMode(Camera.Parameters.FLASH_MODE_AUTO);             }             try {                 mCamera.setParameters(parameters);                 mCamera.startPreview();             } catch (Exception e) {                 e.printStackTrace();             }         }     }  private void releaseCameraSource() {         if (mCamera != null) {             mCamera.setPreviewCallback(null);             mCamera.stopPreview();             mCamera.release();             mCamera = null;         }     }

调用相机的拍摄功能:

点击拍照调用camera.takePicture(null,null,this);

获取拍照回调回来的图片数据

public void onPictureTaken(final byte[] bytes,final Camera camera){    // 拍照回掉回来的 图片数据。         final String filePath = Environment.getExternalStorageDirectory().getPath() + "/DCIM/Camera/";         final String picturePath = System.currentTimeMillis() + ".webp";         final File file = new File(filePath, picturePath);         new Thread(new Runnable() {             @Override             public void run() {                 Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);                 bitmap = rotateBitmapByDegree(bitmap, 90);                 BufferedOutputStream bos = null;                 try {                 //防止拍照保存图片被压缩                     bos = new BufferedOutputStream(new FileOutputStream(file));                     bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);                     bos.flush();                     bos.close();                     bitmap.recycle();                     Intent intent = new Intent(TakePhotoActivity.this,TPreViewPicActivity.class);                     intent.putExtra("filePath",filePath);                     intent.putExtra("picturePath",picturePath);                     startActivityForResult(intent,102);                 } catch (FileNotFoundException e1) {                     e1.printStackTrace();                 } catch (IOException e1) {                     e1.printStackTrace();                 }             }         }).start(); }

接下来要说的就是我们上面说到的保存图片被旋转的问题:

public Bitmap rotateBitmapByDegree(Bitmap bm,int degree){   Bitmap bitmap ;   Matrix matrix = new Matrix();   matrix.postRotate(degree);   try{   bitmap  = Bitmap.createBitmap(bm,0,bm.getWidth,bm.getHeight,matrix,true); }catch(OutOfMemoryError e){   e.printStackTrace(); } if(bitmap == null){ bitmap = bm; } if(bm != bitmap){  bm.recycle(); } return bitmap; } @Override public void onPause(){ super.onPause(); if(camera != null){     if(isPrevew){         camera.stopPreview();         camera.release();         camera= null;         isPreView= false;     }  } } @Override     protected void onResume() {         super.onResume();         openCamera();     }

*#额外要说明的是,android 6.0权限问题,可能会导致首次进入拍照界面黑屏,解决方案在拍照界面之前请求权限;

最后附上请求权限代码:

public void checkPermission() {         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {             requestPermissions(new String[]{Manifest.permission.CAMERA}                     , new TCallPhoneTool.PermissionListener() {                         @Override                         public void onGranted() { //                            openCamera();                         }                         @Override                         public void onRefused(List<String> deniedPermissions) {                             showMissingPermissionDialog();                         }                     });         } else { //            openCamera();         }     }   TCallPhoneTool.PermissionListener mListener ;     final int REQUEST_CODE_STORAGE = 131;     public void requestPermissions(String[] permissions, TCallPhoneTool.PermissionListener listener) {         List<String> deniedPermissions = new ArrayList<>() ;         mListener = listener ;         for (String permission : permissions) {             if (ContextCompat.checkSelfPermission(this,permission) == PackageManager.PERMISSION_DENIED) {                 deniedPermissions.add(permission);             }         }         if (deniedPermissions.size() > 0) {             ActivityCompat.requestPermissions(this,deniedPermissions.toArray(new String[deniedPermissions.size()]),REQUEST_CODE_STORAGE);         } else {             mListener.onGranted();         }     }    public void showMissingPermissionDialog() {         android.support.v7.app.AlertDialog.Builder builder = new android.support.v7.app.AlertDialog.Builder(this);         builder.setTitle(getString(com.to8to.baselib.R.string.tip_permision_miss));         builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {             @Override             public void onClick(DialogInterface dialog, int which) {                 finish();             }         });         builder.setPositiveButton("设置", new DialogInterface.OnClickListener() {             @Override             public void onClick(DialogInterface dialog, int which) {                 startAppSetting();             }         });         builder.setCancelable(false);         builder.show();    public void startAppSetting() {         Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);         intent.setData(Uri.parse("package:" + this.getPackageName()));         startActivity(intent);     }

推荐阅读