@Marox
Человек

Почему фото с передней камеры получается перевернутым?

Реализую в своем приложении возможность съемки фото с передней/задней камеры. Вот код реализации:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder holder;
    Camera camera;
    Context context;
    Camera.Size bestSize;
    static int cameraId;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        this.context = context;
        this.camera = camera;
        holder = getHolder();
        holder.addCallback(this);
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
        }
        catch (IOException e) {
            e.printStackTrace();
            Log.d("camera", "All is terrible");
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        prepareCamera();
        launchPreview();
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    }

    public int getCorrectCameraOrientation() {

        int rotation = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE))
                .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 = 0;
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);

        // back cam
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
            result = ((360 - degrees) + info.orientation);
        } else {
            // front cam
            if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
                result = ((360 - degrees) - info.orientation);
                result += 360;
            }
        }

        return result % 360;
    }

    static public Observable<Camera> createCamera(int cameraId){
        CameraPreview.cameraId = cameraId;

        // open front or rear camera, depends on cameraId
        Observable<Camera> cameraObservable = Observable.create(
                s -> {
                    Camera camera = null;
                    if(Camera.getNumberOfCameras() > 1)
                        camera = Camera.open(cameraId);
                    else {
                        // return front camera if not rear
                        camera = Camera.open(1);
                    }
                    s.onNext(camera);
                    s.onCompleted();
                });
        return  cameraObservable;
    }

    private void launchPreview(){
        try
        {
            camera.setPreviewDisplay(holder);
            camera.startPreview();
        }
        catch(Exception e)
        {
            Log.d("CAMERA", "Error: " + e.getMessage());
        }
    }

    private void getBestPictureResolution(){
        List<Camera.Size> sizes = camera.getParameters().getSupportedPictureSizes();
        Camera.Size result = sizes.get(0);

        for (Camera.Size size: sizes) {
            if(size.width > result.width && size.height > result.height) {
                result = size;
            }
        }
        bestSize = result;
    }

    private void setOptimalPreviewSize() {
        Display display = ((WindowManager)context.getSystemService(Context.WINDOW_SERVICE))
                .getDefaultDisplay();
        Camera.Size size = camera.getParameters().getPreviewSize();

        RectF rectDisplay = new RectF();
        RectF rectPreview = new RectF();

        rectDisplay.set(0, 0, display.getWidth(), display.getHeight());
        rectPreview.set(0, 0, size.height, size.width);

        Matrix matrix = new Matrix();
        matrix.setRectToRect(rectPreview, rectDisplay,
                    Matrix.ScaleToFit.START);
        matrix.mapRect(rectPreview);

        FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams();
        lp.height = (int) (rectPreview.bottom);
        lp.width = (int) (rectPreview.right);
        setLayoutParams(lp);
        requestLayout();
    }

    private void prepareCamera(){
        if(camera != null)
            camera.stopPreview();
        Camera.Parameters params = camera.getParameters();
        if(bestSize == null)
            getBestPictureResolution();
        params.setPictureSize(bestSize.width, bestSize.height);
        params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
        camera.setDisplayOrientation(getCorrectCameraOrientation());
        params.setRotation(getCorrectCameraOrientation());
        setOptimalPreviewSize();
        camera.setParameters(params);
    }
}


Превью с обеих камер работает нормально, с правильным rotation. Если делать фото с задней камеры, то все хорошо: изображение правильно повернуто, а если с передней, то фото перевернуто. Как это исправить?
  • Вопрос задан
  • 1957 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы