안드로이드 개발 중 카메라 방향에 대한 이해

전언
안드로이드 개발에서 카메라를 사용해야 하는 응용 장면이 자주 있는데 처음 접촉한 학우들의 카메라의 방향은 비교적 파악하기 어려운 개념이고 개발할 때 부적절하게 처리하기 쉽다. 본고는 이 부분의 내용을 상세하게 설명하여 이해에 도움을 줄 것이다.
1. 카메라가 포획한 이미지
먼저 간단한 장면을 보고 핸드폰의 후방 카메라를 켜서 촬영한다. 카메라가 포획한 이미지 프레임 데이터는Camera를 통해 촬영할 수 있다.Preview Callback 메타데이터, 즉 카메라의 출력 데이터를 가져옵니다.
void onPreviewFrame(byte[] data, Camera camera);

여기서 우리는 먼저 화면의 미리보기를 무시하고 카메라의 출력만 주목한다.만약 그것을 그림으로 저장하거나 직접 표시한다면, 그림이 원시 화면에 비해 시계 반대 방향으로 90도 회전한 것을 볼 수 있다.
우리가 아이폰으로 똑같이 촬영하면 출력의 결과는 정향적인 그림이다.
2. 카메라의 정방향
왜 출력한 그림이 원시 화면보다 90도 회전했습니까?설비의 카메라에'정방향 각도'가 존재하기 때문에 카메라의 정방향은 무엇입니까?통속적으로 말하면 장비는 사람의 신체에 해당하고 눈은 카메라에 해당하며 눈은 수신한 화면을 뇌에 피드백하여 처리하고 카메라는 수신한 데이터를 응용 프로그램에 처리하는 것과 같다.사람의 눈은 우리의 머리 위로 향하는 방향이 우리의 시각적 정향임을 판단할 수 있다. 그러나 후방 카메라가 판단하는 정향은 휴대전화 물리 스크린이 위로 향하는 방향이 아니라 물리 스크린 오른쪽의 방향이다.만약 사람의 눈이 이 카메라라면 오른쪽이야말로 우리의 시각적 정향이라고 생각한다면 우리가 본 것은 모두 90도로 회전하는 것이 아닐까요?이렇게 하면 비교적 이해하기 쉽다.
위의 그림은 휴대전화가 세로와 수평 방향의 카메라에서'보는'화면이다.고정 장치, 지정된 카메라, 정방향 각도 고정(0/90/180/270), 화면 회전, 가로 세로 화면 전환과 상관없이 일반적으로 화면 오른쪽에 있다(그러나 일부 제조업체가 다른 것으로 수정한 것은 배제하지 않는다).이 각도는 코드에서 Camera.CameraInfo의orientation을 통해 얻을 수 있으며 공식 문서에도 설명이 있다.
The orientation of the camera image. The value is the angle that the camera image needs to be rotated clockwise so it shows correctly on the display in its natural orientation. It should be 0, 90, 180, or 270.
For example, suppose a device has a naturally tall screen. The back-facing camera sensor is mounted in landscape. You are looking at the screen. If the top side of the camera sensor is aligned with the right edge of the screen in natural orientation, the value should be 90. If the top side of a front-facing camera sensor is aligned with the right of the screen, the value should be 270.
출력된 그림이 시계 방향으로 몇 도 회전해야 자연 방향에 정확하게 표시될 수 있다는 뜻이다.이곳의 자연 방향은 제목 표시줄의 왼쪽 상단을 원점으로 하는 스크린 렌더링 좌표계이다. 그림이 회전한 후에 렌더링 좌표계에 놓으면 원시 화면과 같이 정상적으로 보일 수 있다.
위의 빨간색 점은 그림의 좌표 원점을 대표하고 파란색 점은 화면이 좌표를 렌더링하는 원점을 대표한다.회전 처리를 해야만 화면에 미리 보이는 이미지가 정확합니다. 이 회전 각도는orientation의 값입니다.주의, 정방향은 항상 물리 화면의 오른쪽(음량키 저쪽에 정방향 화살표가 있다고 상상),orientation은 카메라의 각도(성인의 눈을 상상)에서 볼 수 있으며, 물리 장치의 정상 방향(수화기 위치에 화살표가 있다고 상상)에서 시계 바늘을 몇 도 돌려야만 정방향 화살표에 도달할 수 있다.그래서 이것에 따라 앞뒤 카메라의 차이를 상상해 보면 이 값은 뒷면 카메라가 90이고 앞면 카메라가 270이다.
아이폰의 카메라 정방향은 물리 장치의 바로 위쪽이고 대응하는 정방향 각도는 0이기 때문에 출력된 이미지는 정방향이다.
3. 이미지를 정확하게 미리 보는 방법
실제로 앱을 미리 보지 않아도 카메라의 입력을 정확하게 얻을 수 있지만 일반 앱은 카메라를 켜면 현재 촬영한 화면을 화면에 표시하는데 이것은 사용자의 기본적인 사용 체험이다.정확한 미리보기 이미지는 카메라가 출력한 이미지를 사용자에게 정확하게 표시할 수 있도록 하는 것이다.
위에서 말한 바와 같이 카메라에서 채취한 이미지는orientation에 따라 회전하고 렌더링 좌표계에 따라 정렬하면 이미지를 정확하게 표시할 수 있다.그러나 이것은 화면 방향이 잠긴 상태에서 좌표계가 항상 물리 화면의 왼쪽 위에 렌더링됩니다.
장치 팽이(자물쇠)를 켜면 화면이 네 방향으로 전환되고 렌더링된 좌표 원점(파란색 점)은 물리적 화면의 네 모서리로 전환됩니다.전면 및 후면 카메라와 상관없이 방향 전환 각도는 activity.getWindowManager().getDefaultDisplay().getRotation();를 통해 얻을 수 있습니다.
이 각도는 물리 장치의 왼쪽 상단을 원점으로 하는 렌더링 좌표계(수화기 왼쪽의 각점)가 시계 바늘을 따라 몇 도 회전해야 현재의 렌더링 좌표계가 될 수 있음을 이해할 수 있다.팽이를 켜면 핸드폰이 어떻게 회전하든 현재의 렌더링 좌표계는 절대 왼쪽 상단을 원점(시각 왼쪽 상단 각점)으로 한다.이 각도는 물리 회전의 각도와 정반대이다.
우리는 현재의 전환 각도 + 카메라의 정방향 각도에 따라 표시 각도를 정확하게 설정하면 된다. 공식 문서에도 기존의 어댑터 코드가 있는데, 상세한 것은 setDisplayOrientation을 보십시오.setDisplayOrientation은 미리보기로 표시된 이미지에만 영향을 주고 onPreviewFrame 콜백 데이터에는 영향을 주지 않습니다.
 public static void setCameraDisplayOrientation(Activity activity,         int cameraId, android.hardware.Camera camera) {
     android.hardware.Camera.CameraInfo info =             new android.hardware.Camera.CameraInfo();
     android.hardware.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;
     }
     camera.setDisplayOrientation(result);
 }

만약 이 코드의 뜻을 이해하지 못한다면 이 그림을 보면 알 수 있다.
파란색 점은 렌더링된 좌표 원점이고 빨간색 점은 출력 이미지의 원점입니다.매번 회전할 때마다 그림의 원점은 절대 위치의 왼쪽 상단으로 바뀐다. setDisplayOrientation이 설정하고자 하는 값은 그림이 시계 방향으로 회전해야 하는 각도로 그림이 렌더링 좌표계에 정확하게 표시되도록 하는 것이다.그림에서도 두 번째 열의 화살표가 시계 방향으로 첫 번째 열의 화살표 각도로 회전해야 한다는 것을 알 수 있다.

좋은 웹페이지 즐겨찾기