카메라 라이브 미리보기가 카메라 스위치에서 멈춤

요아킴 프린 슬루

맞춤형 카메라 앱을 만들고 있습니다. 내가 직면 한 문제는 전면 카메라와 후면 카메라 사이를 전환 할 때 카메라 미리보기가 정지된다는 것입니다. 전화로 전면 또는 후면 카메라로 활동을 시작할 때

boolean opened = safeCameraOpenInView(view, Camera.CameraInfo.CAMERA_FACING_BACK)

조각의 OnCreateView 메서드에서 두 카메라 모두 시작시 예상대로 표시됩니다. 스위치 버튼의 클릭 리스너에서 동일한 메서드를 호출하자마자 카메라가 즉시 정지됩니다.

이것은 여기에있는 질문에 따라 모든 코드가 사용자 지정 클래스 대신 동일한 조각 내에있는 새로운 구현입니다. 사용자 지정 클래스 카메라 라이브 미리보기가 카메라 스위치에서 고정 되지만 결과는 정확히 동일합니다. 나는 그것을 새로운 카메라에 바인딩하기 위해 표면 뷰로 뭔가를해야한다고 확신하지만, 이것을하는 방법을 잃어 버렸다. 아무도 포인터가 있습니까?

내 활동 :

public class Camera2ActivityFragment extends Fragment {

    // Native camera.
    private Camera mCamera;


    // View to display the camera output.
    private CameraPreview mPreview;

    // Reference to the containing view.
    private View mCameraView;

    /**
     * Default empty constructor.
     */
    public Camera2ActivityFragment(){
        super();
    }

    /**
     * Static factory method
     * @param sectionNumber
     * @return
     */
    public static Camera2ActivityFragment newInstance(int sectionNumber) {
        Camera2ActivityFragment fragment = new Camera2ActivityFragment();
        //Bundle args = new Bundle();
        //args.putInt(ARG_SECTION_NUMBER, sectionNumber);
        //fragment.setArguments(args);
        return fragment;
    }

    /**
     * OnCreateView fragment override
     * @param inflater
     * @param container
     * @param savedInstanceState
     * @return
     */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_camera2, container, false);
        boolean opened = safeCameraOpenInView(view, Camera.CameraInfo.CAMERA_FACING_BACK);

        if(opened == false){
            Log.d("CameraGuide","Error, Camera failed to open");
            return view;
        }

        // Trap the capture button.
        Button captureButton = (Button) view.findViewById(R.id.btnCameraStart);
        captureButton.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        // get an image from the camera
                        mCamera.takePicture(null, null, mPicture);
                    }
                }
        );

        Button switchCameraButton = (Button) view.findViewById(R.id.btnSwitchCamera);
        switchCameraButton.setOnClickListener(
                new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        safeCameraOpenInView(getView(), Camera.CameraInfo.CAMERA_FACING_FRONT); //ISSUE OCCURS HERE!
                    }
                }
        );

        return view;
    }

    /**
     * Recommended "safe" way to open the camera.
     * @param view
     * @return
     */
    private boolean safeCameraOpenInView(View view, int camID) {
        boolean qOpened = false;
        releaseCameraAndPreview();
        //mCamera = getCameraInstance(Camera.CameraInfo.CAMERA_FACING_BACK);
        mCamera = getCameraInstance(camID);
        mCameraView = view;
        qOpened = (mCamera != null);

        if(qOpened == true){
            mPreview = new CameraPreview(getActivity().getBaseContext(), mCamera,view);
            FrameLayout preview = (FrameLayout) view.findViewById(R.id.camera_view);
            preview.addView(mPreview);
            mPreview.startCameraPreview();
        }
        return qOpened;
    }

    /**
     * Safe method for getting a camera instance.
     * @return
     */
    public static Camera getCameraInstance(int camID){
        Camera c = null;
        try {
            c = Camera.open(camID); // attempt to get a Camera instance
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return c; // returns null if camera is unavailable
    }

    @Override
    public void onPause() {
        super.onPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        releaseCameraAndPreview();
    }

    /**
     * Clear any existing preview / camera.
     */
    private void releaseCameraAndPreview() {

        if (mCamera != null) {
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
        if(mPreview != null){
            mPreview.destroyDrawingCache();
            mPreview.mCamera = null;
        }
    }

    /**
     * Surface on which the camera projects it's capture results. This is derived both from Google's docs and the
     * excellent StackOverflow answer provided below.
     *
     * Reference / Credit: https://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
     */
    class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

        // SurfaceHolder
        private SurfaceHolder mHolder;

        // Our Camera.
        private Camera mCamera;

        // Parent Context.
        private Context mContext;

        // Camera Sizing (For rotation, orientation changes)
        private Camera.Size mPreviewSize;

        // List of supported preview sizes
        private List<Camera.Size> mSupportedPreviewSizes;

        // Flash modes supported by this camera
        private List<String> mSupportedFlashModes;

        // View holding this camera.
        private View mCameraView;

        public CameraPreview(Context context, Camera camera, View cameraView) {
            super(context);

            // Capture the context
            mCameraView = cameraView;
            mContext = context;
            setCamera(camera);

            // Install a SurfaceHolder.Callback so we get notified when the
            // underlying surface is created and destroyed.
            mHolder = getHolder();
            mHolder.addCallback(this);
            mHolder.setKeepScreenOn(true);
            // deprecated setting, but required on Android versions prior to 3.0
            mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        }

        /**
         * Begin the preview of the camera input.
         */
        public void startCameraPreview()
        {
            try{
                mCamera.setPreviewDisplay(mHolder);
                mCamera.startPreview();
            }
            catch(Exception e){
                e.printStackTrace();
            }
        }

        /**
         * Extract supported preview and flash modes from the camera.
         * @param camera
         */
        private void setCamera(Camera camera)
        {
            // Source: https://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
            mCamera = camera;
            mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes();
            mSupportedFlashModes = mCamera.getParameters().getSupportedFlashModes();

            // Set the camera to Auto Flash mode.
            if (mSupportedFlashModes != null && mSupportedFlashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)){
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                parameters.setRotation(90);
                //parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
                mCamera.setParameters(parameters);
                mCamera.setDisplayOrientation(90);
            }

            requestLayout();
        }

        /**
         * The Surface has been created, now tell the camera where to draw the preview.
         * @param holder
         */
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                mCamera.setPreviewDisplay(holder);

                //mCam = Camera.open();
                //mCam.setPreviewDisplay(holder);

            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        /**
         * Dispose of the camera preview.
         * @param holder
         */
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (mCamera != null){
                mCamera.stopPreview();
            }
        }

        /**
         * React to surface changed events
         * @param holder
         * @param format
         * @param w
         * @param h
         */
        public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

            //Log.e(TAG, "surfaceChanged => w=" + w + ", h=" + h);
            // If your preview can change or rotate, take care of those events here.
            // Make sure to stop the preview before resizing or reformatting it.
            if (mHolder.getSurface() == null){
                // preview surface does not exist
                return;
            }

            // stop preview before making changes
            try {
                mCamera.stopPreview();
                //mCamera.release();
            } catch (Exception e){
                // ignore: tried to stop a non-existent preview
            }

            // set preview size and make any resize, rotate or reformatting changes here
            // start preview with new settings
            try {
                Camera.Parameters parameters = mCamera.getParameters();
                parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
                parameters.setRotation(90);
                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
                mCamera.setParameters(parameters);
                mCamera.setDisplayOrientation(90);
                mCamera.setPreviewDisplay(mHolder);
                mCamera.enableShutterSound(true);
                mCamera.startPreview();

            } catch (Exception e){
                //Log.d(TAG, "Error starting camera preview: " + e.getMessage());
            }
        }

        /**
         * Calculate the measurements of the layout
         * @param widthMeasureSpec
         * @param heightMeasureSpec
         */
        @Override
        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
        {
            /*
            // Source: https://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
            final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
            final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);
            setMeasuredDimension(width, height);

            if (mSupportedPreviewSizes != null){
                mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
            }
            */
            final int width = resolveSize(getSuggestedMinimumWidth(), widthMeasureSpec);
            final int height = resolveSize(getSuggestedMinimumHeight(), heightMeasureSpec);

            if (mSupportedPreviewSizes != null) {
                mPreviewSize = getOptimalPreviewSize(mSupportedPreviewSizes, width, height);
            }

            float ratio;
            if(mPreviewSize.height >= mPreviewSize.width)
                ratio = (float) mPreviewSize.height / (float) mPreviewSize.width;
            else
                ratio = (float) mPreviewSize.width / (float) mPreviewSize.height;

            // One of these methods should be used, second method squishes preview slightly
            setMeasuredDimension(width, (int) (width * ratio));
//        setMeasuredDimension((int) (width * ratio), height);
        }

        /**
         * Update the layout based on rotation and orientation changes.
         * @param changed
         * @param left
         * @param top
         * @param right
         * @param bottom
         */
        @Override
        protected void onLayout(boolean changed, int left, int top, int right, int bottom)
        {
            // Source: https://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
            if (changed) {
                final int width = right - left;
                final int height = bottom - top;

                int previewWidth = width;
                int previewHeight = height;

                if (mPreviewSize != null){
                    Display display = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();

                    switch (display.getRotation())
                    {
                        case Surface.ROTATION_0:
                            previewWidth = mPreviewSize.height;
                            previewHeight = mPreviewSize.width;
                            mCamera.setDisplayOrientation(90);
                            break;
                        case Surface.ROTATION_90:
                            previewWidth = mPreviewSize.width;
                            previewHeight = mPreviewSize.height;
                            break;
                        case Surface.ROTATION_180:
                            previewWidth = mPreviewSize.height;
                            previewHeight = mPreviewSize.width;
                            break;
                        case Surface.ROTATION_270:
                            previewWidth = mPreviewSize.width;
                            previewHeight = mPreviewSize.height;
                            mCamera.setDisplayOrientation(180);
                            break;
                    }
                }

                final int scaledChildHeight = previewHeight * width / previewWidth;
                mCameraView.layout(0, height - scaledChildHeight, width, height);
            }
        }

        /**
         *
         * @param sizes
         * @param width
         * @param height
         * @return
         */
        private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
        {
            final double ASPECT_TOLERANCE = 0.1;
            double targetRatio = (double) height / width;

            if (sizes == null)
                return null;

            Camera.Size optimalSize = null;
            double minDiff = Double.MAX_VALUE;

            int targetHeight = height;

            for (Camera.Size size : sizes) {
                double ratio = (double) size.height / size.width;
                if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                    continue;

                if (Math.abs(size.height - targetHeight) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - targetHeight);
                }
            }

            if (optimalSize == null) {
                minDiff = Double.MAX_VALUE;
                for (Camera.Size size : sizes) {
                    if (Math.abs(size.height - targetHeight) < minDiff) {
                        optimalSize = size;
                        minDiff = Math.abs(size.height - targetHeight);
                    }
                }
            }

            return optimalSize;
        }
    }

    /**
     * Picture Callback for handling a picture capture and saving it out to a file.
     */
    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {

            File pictureFile = getOutputMediaFile();
            if (pictureFile == null){
                Toast.makeText(getActivity(), "Image retrieval failed.", Toast.LENGTH_SHORT)
                        .show();
                return;
            }

            try {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                fos.close();

            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    };

    /**
     * Used to return the camera File output.
     * @return
     */
    private File getOutputMediaFile(){

        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_PICTURES), "Pocket Booth");

        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d("Camera Guide", "Required media storage does not exist");
                return null;
            }
        }

        // Create a media file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        mediaFile = new File(mediaStorageDir.getPath() + File.separator +
                "IMG_"+ timeStamp + ".jpg");

        //DialogHelper.showDialog( "Success!","Your picture has been saved!",getActivity());

        return mediaFile;
    }
}
Anoop M

자, 여기 에서는 카메라의 몇 가지 일반적인 기능을 활성화 하여 카메라사용하여 이미지를 캡처하는 방법에 대한 자습서를 작성하겠습니다 .

1 단계 : 미리보기 클래스 만들기

/**
 * A basic Camera preview class
 */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private static final String TAG = "CameraPreview";
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // If your preview can change or rotate, take care of those events here.
        // Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null) {
            // preview surface does not exist
            return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e) {
            // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        startPreview();
    }

    public void resetCamera(Camera camera) {
        mCamera = camera;
    }

    public void startPreview() {
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();
        } catch (Exception e) {
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

2 단계 : FrameLayout미리보기를 유지하는 데 사용 합니다.

 <FrameLayout
        android:id="@+id/cameraPreview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

3 단계 : camera미리보기 클래스를 가져 와서 보냅니다. 카메라를 전달하기 전에 필요한 매개 변수를 설정해야 할 수도 있습니다.

   /**
     * Create our Preview view and set it as the content of UI.
     */
    private void initCameraPreview(final int cameraId, final boolean createPreview) {
        mCamera = getCameraInstance(cameraId);
        setupCameraParameters(cameraId);

        if (createPreview) {
            mPreview = new CameraPreview(this, mCamera);
            mPreviewHolder.addView(mPreview);
        }
        mReadyToCapture = true;
    }



   /**
     * A safe way to get an instance of the Camera object.
     */
    private Camera getCameraInstance(int cameraId) {
        Camera c = null;
        try {
            c = Camera.open(cameraId); // attempt to get a Camera instance
        } catch (Exception e) {
            e.printStackTrace();
            // Camera is not available (in use or does not exist)
        }
        return c; // returns null if camera is unavailable
    }


   /**
     * Measure and Setup the camera parameters.
     */
    private void setupCameraParameters(int cameraId) {
        boolean hasFlash;

        Camera.Parameters parameters = mCamera.getParameters();

        mPreviewSize = determineBestPreviewSize(parameters);
        parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);

        Camera.Size bestPictureSize = determineBestPictureSize(parameters);
        parameters.setPictureSize(bestPictureSize.width, bestPictureSize.height);

        hasFlash = Util.hasSystemFeature(this, PackageManager.FEATURE_CAMERA_FLASH);
        if (mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            hasFlash = Util.hasFrontCameraFlash(parameters);
        } else {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        }
        if (hasFlash)
            parameters.setFlashMode(mFlashMode);

        int[] orientations = Util.getCameraDisplayOrientation(this, cameraId);

        mDisplayOrientation = orientations[0];
        mLayoutOrientation = orientations[1];

        mCamera.setDisplayOrientation(mDisplayOrientation);

        mCamera.setParameters(parameters);
    }

    private Camera.Size determineBestPreviewSize(Camera.Parameters parameters) {
        List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
        return determineBestSize(sizes);
    }

    private Camera.Size determineBestPictureSize(Camera.Parameters parameters) {
        List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
        return determineBestSize(sizes);
    }

    private Camera.Size determineBestSize(List<Camera.Size> sizes) {
        Camera.Size bestSize = null;

        for (Camera.Size currentSize : sizes) {
            boolean isDesiredRatio = (currentSize.width / 4) == (currentSize.height / 3);
            boolean isBetterSize = (bestSize == null || currentSize.width > bestSize.width);
            boolean isInBounds = currentSize.width <= PICTURE_SIZE_MAX_WIDTH;
            if (isDesiredRatio && isInBounds && isBetterSize) {
                bestSize = currentSize;
            }
        }

        if (bestSize == null) {
            return sizes.get(0);
        }

        return bestSize;
    }

4 단계 : 카메라 교체를위한 쓰기 방법

   /**
     * Swapping between system cameras
     */
    private void swapCamera() {

        if (!(Camera.getNumberOfCameras() > 1)) {
         /* No front facing camera to switch.*/
            return;
        }

        mReadyToCapture = false;

        mCamera.stopPreview();
        releaseCamera(false);

        if (mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK)
            mCurrentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
        else
            mCurrentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;

        initCameraPreview(mCurrentCameraId, false);
        mPreview.resetCamera(mCamera);
        mPreview.startPreview();
    }

5 단계 : 플래시 전환 방법

   /**
     * Toggling camera flash to ON/OFF
     */
    private void toggleFlash() {

        if (Util.hasSystemFeature(this, PackageManager.FEATURE_CAMERA_FLASH)) {

            Camera.Parameters parameters = mCamera.getParameters();


            if (mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                if (!Util.hasFrontCameraFlash(parameters)) {

                 /* Front facing camera doesn\'t supported flash. */

                    return;
                }
            }

            mReadyToCapture = false;

            if (Camera.Parameters.FLASH_MODE_ON.equals(parameters.getFlashMode())) {
                mFlashMode = Camera.Parameters.FLASH_MODE_OFF;

            } else {
                mFlashMode = Camera.Parameters.FLASH_MODE_ON;

            }
            mCameraHandler.post(new Runnable() {
                @Override
                public void run() {

                    mCamera.stopPreview();
                    releaseCamera(false);

                    initCameraPreview(mCurrentCameraId, false);

                    mPreview.resetCamera(mCamera);
                    mPreview.startPreview();
                }
            });

        } else {
            /* warning_no_flash */
        }

    }

6 단계 : 화면 상태 변경 중 카메라 처리 방법

   /**
     * Release the camera for other applications
     */
    private void releaseCamera(boolean remove) {
        if (mCamera != null) {
            if (remove)
                mPreview.getHolder().removeCallback(mPreview);
            mCamera.release();
            mCamera = null;
        }
    }

7 단계 : 유틸리티 클래스.

   /**
     * Check whether the given feature available in s/m
     *
     * @return Returns true if the devices supports the feature, else
     * false.
     */
    public static boolean hasSystemFeature(Context context, String feature) {
        return context.getPackageManager().hasSystemFeature(feature);
    }

   /**
     * Check whether front camera flash feature available in s/m
     */
    public static boolean hasFrontCameraFlash(Camera.Parameters cameraParameters) {
        boolean result = true;
        if (cameraParameters.getFlashMode() == null) {
            result = false;
        }
        List<String> supportedFlashModes = cameraParameters.getSupportedFlashModes();
        if (supportedFlashModes == null || supportedFlashModes.isEmpty()
                || supportedFlashModes.size() == 1 &&
                supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)) {
            result = false;
        }
        return result;
    }

   /**
     * Showing camera in the same orientation as the display
     */
    public static int[] getCameraDisplayOrientation(Activity activity,
                                                    int cameraId) {
        Camera.CameraInfo info =
                new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }
        return new int[]{result, degrees};
    }

8 단계 : 캡처

  // Get an image from the camera
 if (null != mCamera && mReadyToCapture) {
     mCameraOrientationListener.rememberOrientation();
     mCamera.takePicture(mShutter, null, mPicture)
    }

   /**
     * Camera shutter sound callback,
     * used to enable sound while capture
     */
    private Camera.ShutterCallback mShutter = new Camera.ShutterCallback() {
        @Override
        public void onShutter() {

        }
    };

    /**
     * Camera picture callback
     */
    private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            mReadyToCapture = false;


            Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

            int rotation = ((mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK ? mDisplayOrientation :
                    ((360 - mDisplayOrientation) % 360)) + mCameraOrientationListener.getRememberedOrientation()
                    + mLayoutOrientation) % 360;

            if (rotation != 0) {
                Matrix matrix = new Matrix();
                matrix.postRotate(rotation);
                bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
            }


        }
    };

9 단계 : 이미지 회전 처리를위한 카메라 방향 리스너

/**
 * Orientation listener to remember the device's orientation when the user presses
 * the shutter button.
 * <p/>
 * The orientation will be normalized to return it in steps of 90 degrees
 * (0, 90, 180, 270).
 */
public class CameraOrientationListener extends OrientationEventListener {
    private int currentNormalizedOrientation;
    private int rememberedNormalizedOrientation;

    public CameraOrientationListener(Context context) {
        super(context, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    public void onOrientationChanged(int orientation) {
        if (orientation != ORIENTATION_UNKNOWN) {
            currentNormalizedOrientation = normalize(orientation);
        }
    }

    private int normalize(int degrees) {
        if (degrees > 315 || degrees <= 45) {
            return 0;
        }

        if (degrees > 45 && degrees <= 135) {
            return 90;
        }

        if (degrees > 135 && degrees <= 225) {
            return 180;
        }

        if (degrees > 225 && degrees <= 315) {
            return 270;
        }

        throw new RuntimeException("The physics as we know them are no more. Watch out for anomalies.");
    }

    public void rememberOrientation() {
        rememberedNormalizedOrientation = currentNormalizedOrientation;
    }

    public int getRememberedOrientation() {
        return rememberedNormalizedOrientation;
    }
}

10 단계 : 상태 처리

   @Override
    public void onPause() {
        super.onPause();
        mReadyToCapture = false;
        releaseCamera(true);
    }


    @Override
    public void onResume() {
        super.onResume();
        removePreview();
        mReadyToCapture = false;
        smoothCameraLoading();
    }

   private void removePreview() {
        mPreviewHolder.removeAllViews();
    }

   private void smoothCameraLoading() {
        mCameraHandler.post(new Runnable() {
            @Override
            public void run() {
                initCameraPreview(mCurrentCameraId, true);
            }
        });
    }

11 단계 : 사용 된 인스턴스 변수

    private String mFlashMode = Camera.Parameters.FLASH_MODE_OFF;
    private int mCurrentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
    private int mDisplayOrientation;
    private int mLayoutOrientation;
    private boolean mReadyToCapture = false;
    private Camera.Size mPreviewSize;
    private FrameLayout mPreviewHolder;
    private Camera mCamera;
    private CameraPreview mPreview;
    private Handler mCameraHandler;
    private CameraOrientationListener mCameraOrientationListener;
    private FrameLayout mRootView;

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

화면 잠금 후 카메라 미리보기가 멈춤

앱을 연 직후 Android 카메라 미리보기가 멈춤

수면 후 카메라가 멈춤

카메라 미리보기 위에 CustomPaint

전면 카메라에 펼쳐진 카메라 미리보기

UIView에 라이브 카메라 미리보기를 추가하는 방법

Android 용 라이브러리와 같은 TGLAugmentedRealityView? (카메라 미리보기 위치)

카메라 미리보기에서 이미지가 왜곡됨

AVCaptureVideoPreviewLayer (카메라 미리보기)가 배경으로 이동했다가 뒤로 이동 한 후 정지 / 멈춤

라이브 카메라 미리보기에 사용자 정의 카메라 필터 적용-Swift

두 가지보기에서 Android 카메라 미리보기 (멀티 렌즈 카메라 미리보기)

Sony Camera API 초기화-카메라 멈춤

화면 잠금 해제 후 카메라가 멈춤

앱으로 돌아 오면 카메라가 멈춤 (Obj-C)

카메라가 닫히지 못하도록 멈춤

카메라 애플리케이션에서 라이브 카메라 미리보기가 포함 된 레이아웃을 빌드하는 방법 이해

세로 모드에서 카메라 가로 미리보기

Qt GUI에서 라이브 카메라 이미지 표시

라이브 카메라 미리보기에서 특정 픽셀의 색상 가져 오기-Ionic

카메라 미리보기의 SwiftUI 위치 오버레이

카메라 미리보기 위에 직사각형 그리기

디스플레이 카메라에 선을 그리고 싶습니다 (카메라 미리보기)

맞춤형 카메라의 삼성 장치에서 이미지 저장 문제

minSdk 17에서 맞춤형 카메라 작성하기

WebRTC 스위치 카메라

카메라 / 사진 라이브러리에서 Ionic 앱 이미지 업로드

후면 카메라로 사진을 찍을 때 SurfaceView가 2 초 동안 멈춤

라이브 카메라가 아닌 이미지에서 tensorflow 객체 감지

카메라 미리보기 레이어에 Swift 4가 표시되지 않음

TOP 리스트

  1. 1

    Ionic 2 로더가 적시에 표시되지 않음

  2. 2

    JSoup javax.net.ssl.SSLHandshakeException : <url>과 일치하는 주체 대체 DNS 이름이 없습니다.

  3. 3

    std :: regex의 일관성없는 동작

  4. 4

    Xcode10 유효성 검사 : 이미지에 투명성이 없지만 여전히 수락되지 않습니까?

  5. 5

    java.lang.UnsatisfiedLinkError : 지정된 모듈을 찾을 수 없습니다

  6. 6

    rclone으로 원격 디렉토리의 모든 파일을 삭제하는 방법은 무엇입니까?

  7. 7

    상황에 맞는 메뉴 색상

  8. 8

    SMTPException : 전송 연결에서 데이터를 읽을 수 없음 : net_io_connectionclosed

  9. 9

    정점 셰이더에서 카메라에서 개체까지의 XY 거리

  10. 10

    Windows cmd를 통해 Anaconda 환경에서 Python 스크립트 실행

  11. 11

    다음 컨트롤이 추가되었지만 사용할 수 없습니다.

  12. 12

    C #에서 'System.DBNull'형식의 개체를 'System.String'형식으로 캐스팅 할 수 없습니다.

  13. 13

    JNDI를 사용하여 Spring Boot에서 다중 데이터 소스 구성

  14. 14

    Cassandra에서 버전이 지정된 계층의 효율적인 모델링

  15. 15

    복사 / 붙여 넣기 비활성화

  16. 16

    Android Kotlin은 다른 활동에서 함수를 호출합니다.

  17. 17

    Google Play Console에서 '예기치 않은 오류가 발생했습니다. 나중에 다시 시도해주세요. (7100000)'오류를 수정하는 방법은 무엇입니까?

  18. 18

    SQL Server-현명한 데이터 문제 받기

  19. 19

    Seaborn에서 축 제목 숨기기

  20. 20

    ArrayBufferLike의 typescript 정의의 깊은 의미

  21. 21

    Kubernetes Horizontal Pod Autoscaler (HPA) 테스트

뜨겁다태그

보관