IT_Programming/Android_Java

Android Camera Picture Size 선택 방법.

JJun ™ 2013. 7. 16. 07:18

 


 출처: http://lsit81.tistory.com/entry/Android-Camera-Picture-Size-선택-방법


 

 

카메라 사진 촬영을 위해서는

Camera.Parameters.setPictureSize(int width, int height)을 이용하여 사진 크기를

미리 설정해 주어야 합니다. 


그러나 setPictureSize를 하기위해서는 해당 단말기에서 지원되는 해상도를 알아야 하는데

그것은 Camera.Parameters.getSupportedPictureSizes()를 통해서 얻을 수 있습니다. 


그러나 카메라로 개발해 보신 분들은 아시겠지만 getSupportedPictureSizes()로 지원된다고 하고선 실제 사용을하면 촬영이 안되거나 촬영에 문제가 발생되는 경우를 보신 분들도 계실 것 입니다.

 

그 이유는 카메라 Preview 해상도와 촬영 해상도의 비율이 같지 않아서 생긴 문제 입니다. 

 

이 이슈를 해결하려고 먼저 촬영할 Picture Size를 설정하고 거기에 맞는 Preview Size를

아래와 같이 구하여 사용을 하였습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
List<camera.size> previewSizes = cameraAdapter.getSupportedPreviewSizes();
...
optimalSize = getCameraPreviewSize(previewSizes, pictureWidth, pictureHeight, 0.05, targetHeight);
 
private static Camera.Size getCameraPreviewSize(List<camera.size> previewList, int targetPreviewWidth, int targetPreviewHeight, double targetRatio, int targetHeight) {
    final double aspectTolerance = 0.05;
    double      minDiff = Double.MAX_VALUE;
    Size        optimalSize = null;
 
    for (Size size : previewList) {
        double ratio = (double) size.width / size.height;
 
        if (Math.abs(ratio - targetRatio) > aspectTolerance) {
            continue;
        }
 
        if (Math.abs(size.height - targetHeight) < minDiff) {
            optimalSize = size;
            minDiff = Math.abs(size.height - targetHeight);
        }
    }
     
    return optimalSize;
}



그러나 갤럭시 노트에서 확인해 본 결과 촬영 해상도를 1280 * 720으로 설정하고 위 getCameraPreviewSize()통해 얻은 프리뷰 해상도 1280 * 800으로 설정하여 촬영할 경우


프리뷰 화면과 촬영 화면의 비율이 서로 다르게되어 사용자가 화면에서본 이미지 그대로 영상이

촬영되지 않는 문제가 있었습니다.

* getCameraPreviewSize() 알고리즘 상에 문제는 없습니다.


한 마디로 촬영 해상도인 1280 * 720와 비율이 맞는 프리뷰 해상도가 없다는 것이 문제였습니다. 

* 갤럭시 노트의 경우에는 촬영 비율이 틀어지면서 촬영은 되었지만 다른 단말에서는 앱이 죽을 수도 있는 문제 입니다. 


제조사에서 지원 해상도 리스트를 getSupportedPictureSize()로 얻었을때 1280 * 720 같은 크기는 제외를 시켜야되는데... 그렇게 하고 있지를 않더군요... ㅠㅠ 


그래서 실제 촬영 가능한 촬영 해상도만 얻을 수 있는 함수를 한 가지 더 만들어 사용을 했습니다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/**
 * Android에서 지원되는 사진 Size 리스트를 반환한다.
 *
 * @return
 */
public List<camera.size> getSupportedPictureSizes() {
    if (mCamera == null) {
        return null;
    }
 
    List<camera.size> pictureSizes = getParameters().getSupportedPictureSizes();
             
    checkSupportedPictureSizeAtPreviewSize(pictureSizes);
     
    return pictureSizes;
}
 
private void checkSupportedPictureSizeAtPreviewSize(List<camera.size> pictureSizes) {
    List<camera.size> previewSizes = getParameters().getSupportedPreviewSizes();
    Camera.Size pictureSize;
    Camera.Size previewSize;
    double  pictureRatio = 0;
    double  previewRatio = 0;
    final double aspectTolerance = 0.05;
    boolean isUsablePicture = false;
     
    for (int indexOfPicture = pictureSizes.size() - 1; indexOfPicture >= 0; --indexOfPicture) {
        pictureSize = pictureSizes.get(indexOfPicture);
        pictureRatio = (double) pictureSize.width / (double) pictureSize.height;
        isUsablePicture = false;
         
        for (int indexOfPreview = previewSizes.size() - 1; indexOfPreview >= 0; --indexOfPreview) {
            previewSize = previewSizes.get(indexOfPreview);
             
            previewRatio = (double) previewSize.width / (double) previewSize.height;
             
            if (Math.abs(pictureRatio - previewRatio) < aspectTolerance) {
                isUsablePicture = true;
                break;
            }
        }
         
        if (isUsablePicture == false) {
            pictureSizes.remove(indexOfPicture);
            Logger.d(TAG, "remove picture size : " + pictureSize.width + ", " + pictureSize.height);
        }
    }
}


이렇게 해서 사용을 하였더니 촬영에 대한 문제는 말끔히 해결이 되었습니다. 

또한 기본 카메라앱에서 지원되는 촬영 해상도 리스트와, 제가 만든 카메라앱에서 지원되는

촬영 해상도 리스트가 동일하게 노출이되는 것도 확인을 하였습니다.