Android静默拍照实现(界面无卡顿)

来源:互联网 发布:360软件助手 编辑:程序博客网 时间:2024/06/06 14:10

直接上图了。

 /* new Thread(new Runnable() {              @Override              public void run() {                  // 初始化camera并对焦拍照                  initCamera();              }          }).start();*/ //不可以使用new thread()去拍照,new thread()拍照的话,,回调函数PictureCallback会在主线程执行,会导致主线程卡顿,使用handlerThread就不会出现这个问题,回调函数在子线程执行。        HandlerThread  mTakePhotoThread = new HandlerThread("mmTakePhotoThread");          mTakePhotoThread.start();          Handler mTakePhotoHandler = new Handler(mTakePhotoThread.getLooper()) {              @Override              public void handleMessage(Message msg) {                  initCamera();               }          };          mTakePhotoHandler.sendEmptyMessage(1);      }    // 初始化摄像头      private void initCamera() {          // 如果存在摄像头          if (checkCameraHardware(getActivity())) {              // 获取摄像头(首选前置,无前置选后置)              if (openFacingFrontCamera()) {                  Log.i(TAG, "openCameraSuccess");                  // 进行对焦                  autoFocus();              } else {                  Log.i(TAG, "openCameraFailed");              }          }      }  // 对焦并拍照      private void autoFocus() {         try {              // 因为开启摄像头需要时间,这里让线程睡两秒              Thread.sleep(500);          } catch (InterruptedException e) {              e.printStackTrace();          }        Log.i("测试线程拍照", Thread.currentThread().getId()+"");        // 自动对焦          myCamera.autoFocus(myAutoFocus);          // 对焦后拍照          myCamera.takePicture(null, null, myPicCallback);      } // 判断是否存在摄像头      private boolean checkCameraHardware(Context context) {          if (context.getPackageManager().hasSystemFeature(                  PackageManager.FEATURE_CAMERA)) {              // 设备存在摄像头              return true;          } else {              // 设备不存在摄像头              return false;          }      }   // 得到后置摄像头      private boolean openFacingFrontCamera() {          // 尝试开启前置摄像头          Camera.CameraInfo cameraInfo = new Camera.CameraInfo();          for (int camIdx = 0, cameraCount = Camera.getNumberOfCameras(); camIdx < cameraCount; camIdx++) {              Camera.getCameraInfo(camIdx, cameraInfo);              if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {                  try {                      Log.i(TAG, "tryToOpenCamera");                      myCamera = Camera.open(camIdx);                  } catch (RuntimeException e) {                      e.printStackTrace();                      return false;                  }              }          }          // 如果开启前置失败(无前置)则开启后置          if (myCamera == null) {              for (int camIdx = 0, cameraCount = Camera.getNumberOfCameras(); camIdx < cameraCount; camIdx++) {                  Camera.getCameraInfo(camIdx, cameraInfo);                  if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {                      try {                          myCamera = Camera.open(camIdx);                      } catch (RuntimeException e) {                          return false;                      }                  }              }          }          /*try {              // 这里的myCamera为已经初始化的Camera对象              myCamera.setPreviewDisplay(myHolder);          } catch (IOException e) {              e.printStackTrace();              myCamera.stopPreview();              myCamera.release();              myCamera = null;          }  */        myCamera.startPreview();          return true;      }   // 自动对焦回调函数(空实现)      private AutoFocusCallback myAutoFocus = new AutoFocusCallback() {          @Override          public void onAutoFocus(boolean success, Camera camera) {          }      };      // 拍照成功回调函数      private PictureCallback myPicCallback = new PictureCallback() {          @Override          public void onPictureTaken(byte[] data, Camera camera) {              Log.i("测试线程处理拍照", Thread.currentThread().getId()+"");            // 将得到的照片进行270°旋转,使其竖直              Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);              Matrix matrix = new Matrix();              matrix.preRotate(270);              bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(),                      bitmap.getHeight(), matrix, true);             String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")                      .format(new Date());              // 创建并保存图片文件              File pictureFile = new File(getDir(), "IMG_" + timeStamp + ".jpg");             NativeUtil.compressBitmap(bitmap,pictureFile.getPath());//            try {  //                FileOutputStream fos = new FileOutputStream(pictureFile);  //                bitmap.compress(Bitmap.CompressFormat.PNG, 80, fos);  //                fos.close();  //            } catch (Exception error) {  //                Toast.makeText(getActivity(), "拍照失败", Toast.LENGTH_SHORT)  //                        .show();  //                ;  //                Log.i(TAG, "保存照片失败" + error.toString());  //                error.printStackTrace();  //                myCamera.stopPreview();  //                myCamera.release();  //                myCamera = null;  //            }              Log.i(TAG, "获取照片成功");              Toast.makeText(getActivity(), "获取照片成功", Toast.LENGTH_SHORT).show();  ;              myCamera.stopPreview();              myCamera.release();              myCamera = null;          }      };      // 获取文件夹      private File getDir() {          // 得到SD卡根目录          File dir = Environment.getExternalStorageDirectory();          /*         * copy过来的代码。。。懒得删。         * 有根目录吗?         * 没有。         * 那就创建一个根目录!         */        if (dir.exists()) {              return dir;          } else {              dir.mkdirs();              return dir;          }      }

很多博客静默拍照都是开启一个服务,在服务里面搞一个weight。。能实现,但是拍照是在new Thread()中进行的,会导致主界面卡死。 为啥不能用new Thread()请参照大大神博客:

点击看原因

另外用到了一个压缩图片的办法:

NativeUtil.compressBitmap(bitmap,pictureFile.getPath());

这个代码是抄这里的,用的jni,调C压缩,5M的图片压缩完只有70kb。http://www.jianshu.com/p/e9e1db845c21

这里写图片描述

本屌会抄,本屌10K,希望大家都来抄我的代码。。。。

原创粉丝点击