Android-카메라 미리보기가 옆으로 표시됨


123

카메라가 화면에 보는 것을 표시하기 위해 미리보기를 사용하고 있습니다.

모든 것이 잘 작동하고 표면이 생성되고 표면이 설정되고 표면이 표시되도록 할 수 있습니다.

그러나 세로 모드에서는 항상 잘못된 90도 각도로 그림을 표시합니다.

그림에서와 같은 :

대체 텍스트

다음 코드를 사용하면 그림이 똑바로 설정된다는 것을 알고 있습니다.

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

그러나 다른 요소가있는 활동 내에 미리보기가 있으며 내 활동이 가로 모드로 표시되는 것은 의미가 없습니다. (기본적으로 비활성화 됨)

그래서 어쨌든 미리보기의 방향을 변경해야할까요? 나머지 활동을 세로 모드로 올바르게 표시 하시겠습니까?

또는 어쨌든 올바르게 표시되도록 미리보기를 회전하려면?


답변:


145

이 문제는 특정 하드웨어 버그로 시작 나타났다 여기에서 볼 하지만 내가 그것을 구현하는 방법입니다 그래서 mCamera.setDisplayOrientation에 대한 호출 API 8에서 사용할 수 (도)를 사용하여 극복 할 수있다 :

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            
    if (isPreviewRunning) {
        mCamera.stopPreview();
    }

    Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if(display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(height, width);                           
        mCamera.setDisplayOrientation(90);
    }

    if(display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(width, height);                           
    }

    if(display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(height, width);               
    }

    if(display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(width, height);
        mCamera.setDisplayOrientation(180);
    }

    mCamera.setParameters(parameters);
    previewCamera();                      
}

And the previewCamera method :

public void previewCamera() {        
    try {           
        mCamera.setPreviewDisplay(mSurfaceHolder);          
        mCamera.startPreview();
        isPreviewRunning = true;
    } catch(Exception e) {
        Log.d(APP_CLASS, "Cannot start preview", e);    
    }
}

이것은 HTC Desire에 관한 것이었고 처음에는 각 회전 검사에 로깅 문을 입력하여 회전이 무엇인지 말한 다음 장치에서 디버그하고 장치를 회전하는 동안 logCat 출력을 관찰해야했습니다. HTC Desire의 경우 0은 예상했던대로 전화기 였고 (세로), 90 도는 전화기를 시계 반대 방향으로 90도 돌리는 것입니다 (시계 방향이라고 가정 했었습니다). 코드에서 전화기가 90도 또는 180도에있을 때 디스플레이 회전을 수행 할 필요가 없다는 것을 알 수 있습니다. 장치가이를 자체적으로 처리하는 것처럼 보였습니다. 한 점만 제대로 작동하지 않음 : 270도 회전은 장치를 시계 방향으로 90도 회전하고 디스플레이 회전이 그 정도 반향하는 경우이지만 장치를 시계 반대 방향으로 270도 회전하면 제대로 보정되지 않는 것처럼 보입니다.

추신 : 적절한 회전에서 너비와 높이의 교체에 유의하십시오.


7
하지만 setDisplayOrientation (degree); 방법은 양식 2.2를 지원합니다. 하위 버전은 어떻습니까 ?? parameters.setRotation (90); parameters.set ( "방향", "세로"); 작동하지 않습니다. 낮은 버전에 대한 해결책이 있으면 저를 도와주세요.
Vikram 2011

1
항상 세로 모드로 표시되는 미리보기를 앱에 구현했습니다. 저는 항상 화면을 90도 회전 시켰고 이것은 HTC Desire C에서 테스트 할 때까지 모든 장치에서 작동하는 것처럼 보였습니다. 지금이 장치를 테스트하는 데 의존하지 않으므로이 문제가 해결되는지 확인하시기 바랍니다. 마침내 HTC 욕구에 잘 맞았다 고 제안합니다. 감사!
argenkiwi

13
mCamera.setParameters(parameters);표면 치수 내 휴대 전화에 대한 유효한 미리보기 크기하지 않기 때문에 문은, 내 응용 프로그램 충돌 (I 표시 상태 표시 줄을 유지 어쩌면 때문에?). 그러나 매개 변수를 설정하지 않고 mCamera.setDisplayOrientation(90)then 을 사용하는 것도 효과가 있다는 것을 알았 mCamera.setPreviewDisplay(mSurfaceHolder);습니다!
nicopico 2013

3
스위치 문으로 더 깨끗해질 것입니다
Siavash

2
이것은 미리보기가 모든 장치에서 옆으로 있다고 가정하지 않습니까? 일부 장치에서는 옆으로, 다른 장치에서는 똑바로 세워져 있기 때문입니다 .... 장치의 기본 카메라 방향이 휴대폰의 세로 방향과 인라인인지 확인하는 방법이 있습니까?
Siavash

16

디스플레이 방향을 설정해보십시오. 그것은 내 문제를 해결합니다.

 mCamera.setDisplayOrientation(90);

5
저장할 때 세로 이미지를 가로로 저장합니다.
Akanksha Rathore

@Akanksha :이 플래그는 미리보기 표시에만 적용됩니다. 이 버퍼의 방향이 반환 변경되지 않습니다 onPreviewFrame()또는onPictureTaken()
알렉스 콘

13
 public void surfaceCreated(SurfaceHolder holder) {
     mCamera = Camera.open();
     mCamera.setDisplayOrientation(90);
     try {
         mCamera.setPreviewDisplay(holder);
         mCamera.setPreviewCallback(new PreviewCallback() {

             @Override
             public void onPreviewFrame(byte[] data, Camera camera) {
             }
         });

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

이 코드를 시도


3
저장할 때 세로 이미지를 가로로 저장합니다.
Akanksha Rathore

@Akanksha는 아마도 EXIF ​​매개 변수와 관련이 있습니다.
EpicPandaForce

4

전면 카메라에 문제가있었습니다 (거꾸로 문제). 그럼 난에 기록 된 다음과 같은 방법을 사용 안드로이드 오피스 -

public void setCameraDisplayOrientation(Activity activity , int icameraId , Camera camera1s)
    {
        CameraInfo cameraInfo = new CameraInfo();

        Camera.getCameraInfo(icameraId, cameraInfo);

        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

        int degrees = 0; // k

        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 (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
        {
            // cameraType=CAMERATYPE.FRONT;

            result = (cameraInfo.orientation + degrees) % 360;
            result = (360 - result) % 360; // compensate the mirror

        }
        else
        { // back-facing

            result = (cameraInfo.orientation - degrees + 360) % 360;

        }
        // displayRotate=result;
        camera.setDisplayOrientation(result);


    }

3
이 방법은 카메라 문서에서 가져온 것입니다. developer.android.com/reference/android/hardware/…
VinceFior

@VinceFior 그가 공식 문서에서 게시하면 문제가 있습니까?
Ranjith Kumar

1
@RanjithKumar 특히, 저는 그저 출처에 대한 공로를 인정하고 더 많은 맥락을 위해 사람들을 지적하고 싶었습니다. :)
VinceFior

3

나는 mCamera.setDisplayOrientation (90); 그러나 어떤 이유로 다른 접근 방식이 버전 2.3.3에서 작동하지 않기 때문에 비트 맵을 회전했습니다.

비트 맵을 회전하려면 다음을 수행했습니다.

Matrix matrix = new Matrix();
matrix.postRotate(90);
imageView1 = new ImageView(this);
Bitmap bitmap = BitmapFactory.decodeFile(files[i].getAbsolutePath());
Bitmap rotatedBitmap = Bitmap.createBitmap(bitmap , 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
Bitmap scaledBitmap = Bitmap.createScaledBitmap(rotatedBitmap, 80, 80, true);
imageView1.setImageBitmap(scaledBitmap);

0

내 코드를 튜토리얼 코드와 비교했고 마침내 수정 된 것은 내 AndroidManifext.xml에 다음 코드를 넣는 것이 었습니다. <activity>태그에 :

android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation">

0
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;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        e.printStackTrace();
    }

    Camera.Parameters parameters = mCamera.getParameters();
    Display display = ((WindowManager) getContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay();

    if (display.getRotation() == Surface.ROTATION_0) {
        parameters.setPreviewSize(h, w);
        mCamera.setDisplayOrientation(90);
    }

    if (display.getRotation() == Surface.ROTATION_90) {
        parameters.setPreviewSize(w, h);
        mCamera.setDisplayOrientation(0);
    }

    if (display.getRotation() == Surface.ROTATION_180) {
        parameters.setPreviewSize(h, w);
        mCamera.setDisplayOrientation(270);
    }

    if (display.getRotation() == Surface.ROTATION_270) {
        parameters.setPreviewSize(w, h);
        mCamera.setDisplayOrientation(180);
    }

    previewCamera();
}

public void previewCamera() {
    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        //Log.d(APP_CLASS, "Cannot start preview", e);
        e.printStackTrace();
    }
}

0

SENSOR_ORIENTATION 값이 90 도로 하드 코딩하는 대신 회전에 사용할 값을 설명 할 것이라고 생각합니다.

CameraManager manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        if (manager == null) {
            Log.i(TAG, "camera manager is null");
            return;
        }
        for (String id: manager.getCameraIdList()) {
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
            Integer orientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
            Log.i(TAG, "camera sensor orientation is " + orientation);
        }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.