IT_Programming/Android_Java

[Android] Camera ICS에서 선택 포커싱

JJun ™ 2013. 7. 16. 07:02

 


 출처: http://lsit81.tistory.com/entry/Android-Camera-ICS에서-선택-포커싱


 

안드로이드에서 카메라를 사용시 Android ICS 버전부터 사용자가 선택한 영역을 기준으로

포커싱을 할 수 있는 기능을 제공하고 있습니다. 


이에 선택 영역 포커싱을 하는 방법을 알아보도록 하겠습니다. 


참고로 Android Developer Site에  Focus Area에 대해서 설명이 자세하게 나와 있으며,

여기서는 간단한 설명과 직접 개발하면서 구현한 내용을 설명을 드리도록하겠습니다. 


Android에서 Focusing이 가능한 영역에 대한 좌표 체계는 아래 그림과 같이 


세로 : -1000 ~ 1000

가로 : -1000 ~ 1000


입니다.


 

 



그러나 View의 Touch 좌표는 왼쪽 상단을 기준으로 


세로 : 0 ~ View.getWidth()

가로 : 0 ~ View.getHeight()


의 범위를 같고 있기때문에 이를 매핑해주는 작업이 필요합니다. 


* 주의 사항

Android Developer Site에있는 가이드는 프리뷰 영상이 가로 기준으로 나왔기 때문에 
Camera.setDisplayOrientation(90);을 이용하여 구현한 경우 약간의 추가 매핑 작업이 더 필요합니다. 

 


 

아래 소스는 이러한 매핑 작업을 하는 소스 입니다. 


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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
private void setAutoFocusArea(Camera camera, int posX, int posY,
                            int focusRange, boolean flag, Point point) {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
        /** 영역을 지정해서 포커싱을 맞추는 기능은 ICS 이상 버전에서만 지원됩니다.  **/
        return;
    }
     
    if (posX < 0 || posY < 0) {
        setArea(camera, null);
        return;
    }
     
    int touchPointX;
    int touchPointY;
    int endFocusY;
    int startFocusY;
     
    if (!flag) {
        /** Camera.setDisplayOrientation()을 이용해서 영상을 세로로 보고 있는 경우. **/
        touchPointX = point.y >> 1;
        touchPointY = point.x >> 1;
         
        startFocusY = posX;
        endFocusY   = posY;
    } else {
        /** Camera.setDisplayOrientation()을 이용해서 영상을 가로로 보고 있는 경우. **/
        touchPointX = point.x >> 1;
        touchPointY = point.y >> 1;
         
        startFocusY = posY;
        endFocusY = point.x - posX;
    }
     
    float startFocusX   = 1000F / (float) touchPointY;
    float endFocusX     = 1000F / (float) touchPointX;
     
    /** 터치된 위치를 기준으로 focusing 영역으로 사용될 영역을 구한다. **/
    startFocusX = (int) (startFocusX * (float) (startFocusY - touchPointY)) - focusRange;
    startFocusY = (int) (endFocusX * (float) (endFocusY - touchPointX)) - focusRange;
    endFocusX = startFocusX + focusRange;
    endFocusY = startFocusY + focusRange;
     
    if (startFocusX < -1000)
        startFocusX = -1000;
     
    if (startFocusY < -1000)
        startFocusY = -1000;
     
    if (endFocusX > 1000) {
        endFocusX = 1000;
    }
     
    if (endFocusY > 1000) {
        endFocusY = 1000;
    }
     
    /*
     * 주의 : Android Developer 예제 소스 처럼 ArrayList에 Camera.Area를 2개 이상 넣게 되면
     *          에러가 발생되는 것을 경험할 수 있을 것입니다.
     **/
    Rect rect = new Rect((int) startFocusX, (int) startFocusY, (int) endFocusX, (int) endFocusY);
    ArrayList<Camera.Area> arraylist = new ArrayList<Camera.Area>();
    arraylist.add(new Camera.Area(rect, 1000)); // 지정된 영역을 100%의 가중치를 두겠다는 의미입니다.
     
    setArea(camera, arraylist);
}




터치된 좌표를 매핑 구했으면 AutoFocusing을 요청하기 전에 Camera.Parameters에 선택된 Focusing 영역을

설정하는 방법은 아래와 같습니다.


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
private void setArea(Camera camera, List<Camera.Area> list) {
    boolean     enableFocusModeMacro = true;
     
    Camera.Parameters parameters;
    parameters = camera.getParameters();
 
    int         maxNumFocusAreas    = parameters.getMaxNumFocusAreas();
    int         maxNumMeteringAreas = parameters.getMaxNumMeteringAreas();
     
    if (maxNumFocusAreas > 0) {
        parameters.setFocusAreas(list);
    }
 
    if (maxNumMeteringAreas > 0) {
        parameters.setMeteringAreas(list);
    }
     
    if (list == null || maxNumFocusAreas < 1 || maxNumMeteringAreas < 1) {
        enableFocusModeMacro = false;
    }
 
    if (enableFocusModeMacro == true) {
        /*
         * FOCUS_MODE_MACRO을 사용하여 근접 촬영이 가능하도록 해야
         * 지정된 Focus 영역으로 초점이 좀더 선명하게 잡히는 것을 볼 수 있습니다.
         */

        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);

        Logger.d(TAG, "focus mode macro");
    } else {
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
        Logger.d(TAG, "focus mode auto");
    }
    camera.setParameters(parameters);
}



그리고 AutoFocus 영역을 설정하였으면 "public final void autoFocus (Camera.AutoFocusCallback cb)"을 통해서 AutoFocusing을 시작하면 됩니다. 


예제 파일을 첨부하였으니 좀더 자세한 구현 사항은 예제를 참고해주시기 바랍니다.

AndroidCamera.zip

 

 

 

AndroidCamera.zip
0.17MB