美文网首页
Camera 实现预览拍照

Camera 实现预览拍照

作者: trythinking | 来源:发表于2018-05-11 17:29 被阅读42次

    openCamera 流程

    CameraActivity.java

        @Override
        public void onCreateTasks(Bundle state) {
            ...
            // oncreate manager initialize
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR.execute(mOncreateManagerInitialize);
            // oncreate - onecameramanager
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR.execute(mOncreateOneCameraManager);
            // oncreate modules info and set current module
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR
                    .execute(mOncreateModulesInfoAndCurrentModule);
            // oncreate - camera controller
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR.execute(mOncreateCameraController);
            // oncreate - module data setting
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR.execute(mOnCreateDataSeting);
            // oncreate - request open camera
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR.execute(mOncreateOpencamera);
            // other task
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR
                    .execute(mOncreateOtherTaskInOncreateProcess);
            CameraFilmstripDataAdapter.THREAD_POOL_EXECUTOR.execute(mOncreateOtherTask);
            
            // init module ui
            postInit();
            ...
        }
    
        // oncreate - request open camera
        private Runnable mOncreateOpencamera = new Runnable() {
    
            @Override
            public void run() {
                ...
                mCameraController.requestCamera(
                        mDataModuleManager.getInstance(CameraActivity.this)
                                .getTempCameraModule().getInt(Keys.KEY_CAMERA_ID, 0),
                        mCurrentModule.useNewApi());
                ...
            }
        };
    

    CameraController.java

        @Override
        public void requestCamera(int id, boolean useNewApi) {
            ...
            checkAndOpenCamera(cameraManager, id, mCallbackHandler, this);
            ...
        }
    

    接下来分析 checkAndOpenCamera 流程

    checkAndOpenCamera .png

    最后通知每个 implements ModuleController 的模式,Camera 已经处于可用状态

    以 PhotoModule 分析开启预览流程

    PhotoModule.java

        @Override
        public void onCameraAvailable(CameraProxy cameraProxy) {
            ...
            startPreview(true);
            ...
        }
    
        protected void startPreview(boolean optimize) {
            ...
    
            // update Settings before start preview
            if(settingchange){
                settingchange = false;
            } else {
                updateSettingAfterOpencamera(optimize);
            }
    
            // 设置预览SurfaceHolder
            if (isUseSurfaceView()) {
                if (optimize) {
                    mCameraDevice.setPreviewDisplay(mActivity.getCameraAppUI().getSurfaceHolder());
                } else {
                    mCameraDevice.setPreviewDisplayWithoutOptimize(
                            mActivity.getCameraAppUI().getSurfaceHolder());
                }
            } else {
                if (optimize) {
                    mCameraDevice.setPreviewTexture(mActivity.getCameraAppUI().getSurfaceTexture());
                } else {
                    mCameraDevice.setPreviewTextureWithoutOptimize(mActivity.getCameraAppUI()
                            .getSurfaceTexture());
                }
            }
    
            ...
    
            // 设置预览回调
            CameraAgent.CameraStartPreviewCallback startPreviewCallback
                    = new CameraAgent.CameraStartPreviewCallback() {
                @Override
                public void onPreviewStarted() {
                    ...
                }
            };
    
            // 开始预览
            doStartPreview(startPreviewCallback, mCameraDevice);
            ...
        }
    
        protected void doStartPreview(CameraAgent.CameraStartPreviewCallback startPreviewCallback, 
                                      CameraAgent.CameraProxy cameraDevice) {
            // 开始预览
            if (useNewApi()) {
                mCameraDevice.startPreview();
                startPreviewCallback.onPreviewStarted();
            } else {
                mCameraDevice.startPreviewWithCallback(new Handler(Looper.getMainLooper()),
                        startPreviewCallback);
            }
            ...
        }
    

    拍照流程

    PhotoModule.java

        @Override
        public boolean capture() {
            ...
            // apply Settings
            mCameraDevice.applySettings(mCameraSettings);
    
            // Set JPEG orientation. Even if screen UI is locked in portrait, camera
            // orientation should
            // still match device orientation (e.g., users should always get
            // landscape photos while
            // capturing by putting device in landscape.)
            mCameraDevice.setJpegOrientation(mJpegRotation);
            
            // takePicture start!
            mCameraDevice.takePicture(mHandler,
                    new ShutterCallback(false),
                    mRawPictureCallback, mPostViewPictureCallback, new JpegPictureCallback(loc));
            ...
            return true;
        }
    
        private final class JpegPictureCallback implements CameraPictureCallback {
            Location mLocation;
    
            public JpegPictureCallback(Location loc) {
                ...
            }
    
            @Override
            public void onPictureTaken(final byte[] originalJpegData,
                                       final CameraProxy camera) {
                ...
                // 播放拍照音
                mCameraSound.play(MediaActionSound.SHUTTER_CLICK);
                ...
                // 更新缩略图
                startPeekAnimation(originalJpegData);
                ...
                // 如果是三方调用拍照则 stopPreview
                if (mIsImageCaptureIntent) {
                    stopPreview();
                }
                ...
                // 重新 startPreview
                if (!mIsImageCaptureIntent
                        && mContinuousCaptureCount <= 0 && isLastCallback()) {
                    setupPreview();
                }
                ...
                // 保存图片
                saveFinalPhoto(originalJpegData, name, exif, camera, burstMode);
                ...
            }
        }
    

    Q:为什么 takePicture 后需要重新 startPreview

    A:

        /**
         * <p>This method is only valid when preview is active (after
         * {@link #startPreview()}).  Preview will be stopped after the image is
         * taken; callers must call {@link #startPreview()} again if they want to
         * re-start preview or take more pictures. This should not be called between
         * {@link android.media.MediaRecorder#start()} and
         * {@link android.media.MediaRecorder#stop()}.
         */
        public final void takePicture(ShutterCallback shutter, PictureCallback raw,
                PictureCallback postview, PictureCallback jpeg) {
        }
    

    相关文章

      网友评论

          本文标题:Camera 实现预览拍照

          本文链接:https://www.haomeiwen.com/subject/koxqdftx.html