태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.

티스토리 툴바


멀티미디어/Camera2009/12/28 10:19


이 게시물을 무단으로 사용하는 행위(비영리, 영리 포함)는 CCL 2.0 저작자 표시-비영리-변경금지 라이센스에 의거하여 금지되어 있습니다. 원본 글의 출처 및 저작자를 표시해 주신다면 글의 스크랩은 자유롭게 하실 수 있습니다. 단, 비영리 목적의 발표(스터디 등)에 위 글을 사용하고 싶으신 분은 제게 미리 메일로 문의 부탁드립니다.

저작권과 관련된 자세한 사항은 이곳을 참조해 주시기 바랍니다.


강좌 작성환경
SDK Version : Android SDK 1.6, release 2
ADT Version : 0.9.5

추후 SDK업데이트로 인해 글의 내용과 최신 SDK 내용간 차이가 있을 수 있습니다.

지난 글에 이어서 이번 글에서는 카메라 프리뷰를 SurfaceView에 표시하는 방법에 대해 알아보도록 하겠습니다.
카메라 프리뷰 화면이 우리가 만든 SurfaceView에 표시되어야 하므로, SurfaceView를 완전하게 구현해 주어야 합니다.
아래는 우리가 만든 SurfaceView를 상속한 클래스, Preview 클래스의 전체 코드입니다.


class Preview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;
    
    Preview(Context context) {
        super(context);
        
        // SurfaceHolder.Callback을 설정함으로써 Surface가 생성/소멸되었음을
        // 알 수 있습니다.
        mHolder = getHolder();
        mHolder.addCallback(this);
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // Surface가 생성되었다면, 카메라의 인스턴스를 받아온 후 카메라의
        // Preview 를 표시할 위치를 설정합니다.
        mCamera = Camera.open();
        try {
           mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // 다른 화면으로 돌아가면, Surface가 소멸됩니다. 따라서 카메라의 Preview도 
        // 중지해야 합니다. 카메라는 공유할 수 있는 자원이 아니기에, 사용하지 않을
        // 경우 -액티비티가 일시정지 상태가 된 경우 등 - 자원을 반환해야합니다.
        mCamera.stopPreview();
        mCamera = null;
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // 표시할 영역의 크기를 알았으므로 해당 크기로 Preview를 시작합니다.
        Camera.Parameters parameters = mCamera.getParameters();
        parameters.setPreviewSize(w, h);
        mCamera.setParameters(parameters);
        mCamera.startPreview();
    }

}

이전 글에서는 아직 surfaceCreated, surfaceDestroyed, surfaceChanged 메소드가 구현되어있지 않았는데, 여기에서 이 메소드들까지 구현되어 있는 것을 확인할 수 있습니다. 하나하나씩 차근차근 살펴보도록 하겠습니다.

class Preview extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera; // Camera객체 추가

우선, SurfaceView에 카메라에서 받은 영상을 표시하기 위해 Camera객체가 추가된 것을 확인할 수 있습니다.

    public void surfaceCreated(SurfaceHolder holder) {
        // Surface가 생성되었다면, 카메라의 인스턴스를 받아온 후 카메라의
        // Preview 를 표시할 위치를 설정합니다.
        mCamera = Camera.open();
        try {
           mCamera.setPreviewDisplay(holder);
        } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }
    }
그 다음, surfaceCreated 메소드의 구현부입니다.
마치 액티비티의 생애주기 메소드 중 하나인 onCreate(Bundle)의 형태와 유사합니다. 이 메소드를 구현함으로써 SurfaceView가 생성되었을 때, 즉 "화면에 표시" 될 때 해야 할 동작을 처리할 수 있습니다.

여기에서는 카메라 객체를 받아와 카메라로부터 영상을 받을 수 있도록 초기화해주는 동작을 수행하고 있습니다. (Camera.open()) 그 다음, setPreviewDisplay(holder)메소드를 통해 카메라로부터 받은 프리뷰 영상을 어디에 표시해줄지 지정하고 있습니다.

앞의 글에서 SurfaceView는 SurfaceView 자체가 내용을 표시하는 것이 아니라 내부의 SurfaceHolder를 통해 최종적으로는 Surface라는 객체 위에 그 내용을 표시한다고 하였는데, 위의 경우는 아래와 같이 카메라의 영상이 처리된다고 볼 수 있습니다.


그 다음을 한번 보도록 하죠. 예외처리 부분이군요.

 } catch (IOException exception) {
            mCamera.release();
            mCamera = null;
            // TODO: add more exception handling logic here
        }

오류가 발생해서 프리뷰 화면을 제데로 표시하지 못했다면, release() 메소드를 사용하여 카메라의 자원을 다시 반환하는 것을 확인할 수 있습니다. 카메라는 여러 곳에서 공유할 수 있는 자원이 아니기에 카메라 객체의 사용이 끝났다면 위와 같이 release() 메소드를 사용하여 자원을 반환해야 합니다. 그렇지 않으면 다른 문제가 발생할 수 있습니다. :(

public void surfaceDestroyed(SurfaceHolder holder) {
        // 다른 화면으로 돌아가면, Surface가 소멸됩니다. 따라서 카메라의 Preview도 
        // 중지해야 합니다. 카메라는 공유할 수 있는 자원이 아니기에, 사용하지 않을
        // 경우 -액티비티가 일시정지 상태가 된 경우 등 - 자원을 반환해야합니다.
        mCamera.stopPreview();
        mCamera = null;
    }

그 다음, surfaceDestroyed 메소드 구현부입니다. 이 메소드는 SurfaceView가 더이상 화면에 표시되지 않을 때 호출됩니다. 일반적인 View는 액티비티가 일시정지 상태가 된 경우에도 계속 화면에 그 내용을 표시하지만, SurfaceVIew의 경우 표시하는 내용이 다른 뷰에 비해 복잡하기에 굳이 액티비티가 비활성 상태일때 그 내용을 표시할 이유가 없겠죠. 

따라서, stopPreview() 메소드를 사용하여 카메라의 프리뷰 영상을 표시하는 것을 중단하고, 카메라 객체를 소멸시킵니다.

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // 표시할 영역의 크기를 알았으므로 해당 크기로 Preview를 시작합니다.
        Camera.Parameters parameters = mCamera.getParameters(); // (1)
        parameters.setPreviewSize(w, h); // (2)
        mCamera.setParameters(parameters); // (3)
        mCamera.startPreview();
    }

다음은 surfaceChanged메소드입니다. 이 메소드는 surfaceCreated()메소드 호출 이후에 호출되는 메소드로, Surface의 크기에 따라 실질적으로 어떻게 내용을 표시할지를 처리해주는 메소드입니다.

여기에서는 카메라의 여러 설정값들을 담고 있는 parameters를 받아온 후(1), 프리뷰의 크기를 지정합니다.(2) 그 후, setParameters()에 방금 카메라 프리뷰 크기를 수정한 parameter 객체를 인자로 넘겨줌으로써 카메라 객체에서 프리뷰 영상을 표시할 영역의 크기를 설정해주게 됩니다. (3)

이 과정이 모두 끝났다면, startPreview() 메소드를 통해 최종적으로 카메라 프리뷰 영상을 표시해주게 됩니다.

여기까지 해서 SurfaceView 부분의 구현이 모두 끝났습니다. 실질적으로 카메라의 영상을 처리하는 부분은 여기에서 끝났으므로, 남은 것들은 액티비티를 구성하고, 이 뷰의 객체를 생성한 후 액티비티의 화면으로 표시해주는 과정이 남았습니다. 
액티비티 구현을 보도록 하죠.

public class CameraPreview extends Activity {    
    private Preview mPreview;
    
    @Override
	protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        // Hide the window title.
        requestWindowFeature(Window.FEATURE_NO_TITLE);
    
        // Create our Preview view and set it as the content of our activity.
        mPreview = new Preview(this);
        setContentView(mPreview);
    }

}
다른 특이한 것들은 별로 없고, 액티비티의 이름을 표시해주는 타이틀바를 표시하지 않기 위해 requestWindowFeature(Window.FEATURE_NO_TITLE) 를 사용하는 것을 확인할 수 있습니다.

자 이제 거의 다 끝났습니다. 카메라를 사용하기 위해서는 권한이 필요하므로, 메니페스트 파일에 권한을 추가합니다.


위와 같이 메니페스트 파일의 Permission 탭으로 이동한 후, Add..버튼을 누릅니다.


Uses Permission을 선택한 후, OK 버튼을 클릭합니다.


새로 Uses Permission 항목에 카메라 사용 권한인 android.permission.CAMERA 를 선택해주면 권한 추가가 완료됩니다.

그리고, 메니페스트 파일을 열어 수동으로 <uses-feature android:name="android.hardware.camera"/> 를 추가합니다.

 
이 기능은 SDK버전을 선언하는 것과 비슷하게 카메라가 없는 장치에서는 아예 어플리케이션이 설치가 되지 않도록 하는 옵션입니다. 안드로이드를 사용하는 장치가 한두가지가 아니므로 이런 식으로 각 장치의 특성에 맞도록 적절히 조치를 해 주는 것이죠.

마지막으로, 액티비티를 landscape 모드로 표시하기 위해 메니페스트 파일을 열어 Application 탭으로 간후,


Screen orientation을 landscape로 바꾸어줍니다. 이렇게 하면 이 액티비티는 항상 landscape 모드로 표시되게 됩니다.


이 과정이 모두 끝났다면, 어플리케이션을 실행시켜봅시다. 카메라 미리보기가 잘 표시되는 것을 확인할 수 있습니다 :)



소스파일 첨부합니다.


저작자 표시 비영리 변경 금지
크리에이티브 커먼즈 라이선스
Creative Commons License


안드로이드 정보, 강좌를 누구보다 빨리 접하고 싶으신가요?

그렇다면 이메일 구독 혹은  구글 리더에 피드 추가 를 통해 업데이트되는 최신 글들을 받아보실 수 있습니다. :)




TRACKBACK http://androidhuman.tistory.com/trackback/308 관련글 쓰기

댓글을 달아 주세요

  1. 커니님 마지막 사진은 디바이스에 올리셔서 찍으신겁니까??

    교수님께서.ㅡ.ㅡ... 카메라 사용하는 걸로 하나짜라고 하시는데.ㅡ.ㅡ 있는거라고는
    컴퓨터와 웹캠 뿐이라서요^^.

    2009/12/29 16:11 [ ADDR : EDIT/ DEL : REPLY ]
    • 넵 실제 기기로 찍은거에요~
      웹캠을 이용해서 하는 방법도 본 것 같은데..검색해보면 금방 나올 겁니다 :)

      2009/12/29 16:45 [ ADDR : EDIT/ DEL ]
  2. 커니님
    버튼 누르면 다른 화면으로 옮겨주는 기능의 이름이 뭡니까..;;
    어제 본것같은데.. 지금 찾을려니까.ㅡ.ㅡ 안보이는 이 이상한현상!!!!..ㅎㅎㅎㅎ

    ... 참.ㅠ.ㅠ 다음부터는 페이지를 저장하는 습관을 들여야겠습니다..ㅠ.ㅠ

    ps. 방금 트위터에서 떴네요. 칸드로이드 저널 창간호.ㅡ.ㅡ;;
    http://sbroh.wordpress.com/2010/01/05/kandroid_journal_1/

    2010/01/05 13:31 [ ADDR : EDIT/ DEL : REPLY ]
    • 인텐트 말씀하시는건가요? ㅇㅅㅇ?
      아니면 OnClickListener??

      2010/01/05 18:06 [ ADDR : EDIT/ DEL ]
    • 우선 찾아는 놨습니다..ㅎㅎㅎ.ㅡ.ㅡ;; flipper였던가.ㅡ.ㅡ;;;

      그걸로 사용이 가능하더라구요.ㅡ.ㅡ 그래서 내일 한번 짜볼려구요^^.;
      인텐트도 가능하군요.ㅡ.ㅡ 오호.ㅡ.ㅡ...

      2010/01/05 22:06 [ ADDR : EDIT/ DEL ]
  3. 디알엑스

    커니님 안드로이드 증강현실에 관해 질문할게 좀 있는데, 잠수가 풀리셨으면 답변 부탁좀 드리겠습니다 ^^

    2010/03/23 22:20 [ ADDR : EDIT/ DEL : REPLY ]
    • 그쪽은 저보단 펍이나 안드로이드사이드를 이용하시는게 좋을 것 같아요. 전 깊게(...)는 잘 모릅니다 :)

      2010/03/27 08:01 [ ADDR : EDIT/ DEL ]
  4. 예제를 보고 궁금한것이 있어 문의 드립니다 .
    제가 이번에 탭뷰 안에 위 소스를 구현해보니 상단의 탭뷰까지 회전되어 탭뷰가 화면을 가려버리는 사태가 발생하더군요 .
    카메라 속성 파라미터에 set("roation",90) 이나 Roation(90) 만주어서 프리뷰만 회전시키려 했으나 그런건 안되더군요 ... ㅠ_ㅠ
    서페이스 뷰만 회전시킬수있나요 ?

    2010/04/10 09:45 [ ADDR : EDIT/ DEL : REPLY ]
  5. 바람풍경

    CameraPreview예제 잘 봤습니다..
    위소스 받아서 실행해 보니 잘되긴 하는데요..
    뒤로가기 버튼으로 메뉴로 돌아갔다가 다시 CameraPreview를 실행시키면
    한번에러가 나고 다시 실행시키면 제대로 동작하는데
    이거 생명주기 때문에 그런건가요?

    2010/06/14 18:02 [ ADDR : EDIT/ DEL : REPLY ]
  6. Radio

    /바람풍경

    public void surfaceDestroyed(SurfaceHolder holder)
    {
    mCamera.stopPreview();
    mCamera.release(); << 추가 ;;
    mCamera = null;
    }


    하시면 됩니다

    2010/07/06 14:30 [ ADDR : EDIT/ DEL : REPLY ]
  7. 땅콩사탕

    좋은 강좌 감사합니다. 이 카메라 프리뷰 위에 반투명한 이미지를 겹쳐쓰려면 어떤식으로 해야할지 조언좀 구할 수 있을까요??

    2010/09/01 10:33 [ ADDR : EDIT/ DEL : REPLY ]
    • RelativeLayout 등으로 메인 레이아웃을 작성한 후, 이미지를 원하는 곳에 배치하면 됩니다.

      2010/09/05 11:25 [ ADDR : EDIT/ DEL ]
  8. 땅콩사탕

    답변 감사합니다. 그런데 메인 레이아웃을 작성한 후 이 레이아웃을 불러오는 부분이 어디에 들어가야 하는지 이해가 잘 안됩니다.

    2010/09/06 10:59 [ ADDR : EDIT/ DEL : REPLY ]
    • 레이아웃을 불러온 후 onCreate(), onResume() 등에서 레이아웃을 불러오시면 됩니다.

      2010/09/12 15:30 [ ADDR : EDIT/ DEL ]
  9. 감사합니다 덕분에 쉽게 썼네요 =ㅅ=
    요즘 나오는 안드로이드책은 빈약해서 인터넷 자료를 보는게 훨씬 낫군요 ㅎ

    2010/09/13 11:26 [ ADDR : EDIT/ DEL : REPLY ]
  10. sehll

    후방 카메라 말고 전면 카메라를 사용할려고 하는데. 전면 카메라 예제는 혹시 없나요?

    2011/01/31 12:04 [ ADDR : EDIT/ DEL : REPLY ]
    • 전면 카메라 API는 최근(안드로이드 2.3)에 추가되었습니다.
      이전 버전에서는 기기별로 전면 카메라를 사용하는 방법이 달라서 범용적으로 적용하기가 어렵습니다.

      2011/01/31 12:41 [ ADDR : EDIT/ DEL ]
  11. 케이

    커니님 쓰신 책보면서 공부 중인데, 에뮬에서만 해보다 오늘 드디어 실제 단말기에 돌려봤습니다.
    그런데 8장의 카메라 사용한 예제가 넥서스s 단말기에서 작동이 안되네요 ㅠ
    처음에 실행하려고 하면 "죄송합니다....예상치 않게 중지되었습니다. 다시 시도해 주세요." 메세지 뜨며 실패..
    안드로이드 2.3.3인데, 무엇이 문제인지 의심가는 점이라도 있으신가요??

    ----
    아 그리고 실행실패 후에, 원래 잘 되던 기본 카메라 사용하려고 하면 "카메라 오류. 카메라에 연결할 수 없습니다." 뜨네요ㅠ

    2011/03/03 20:23 [ ADDR : EDIT/ DEL : REPLY ]
  12. 행인

    항상 커니님의 글 잘 보고 있습니다. 펍에서도 그렇구요 ^^
    카메라뷰 위에 이미지를 띄우려고 하던중
    RelativeLayout을 생성하고 서피스뷰와 카메라뷰를 애드 시켰습니다.
    그리고 onDraw()에서 이미지를 그려주려고 하는데 이미지는 잘 나옵니다만
    PorterDuffXfermode(PorterDuff.Mode.LIGHTEN);
    위와 같이 광원효과를 주려고 하면 뷰가 다르게 설정 되있어서 하나의 이미지만 먹힙니다.

    이 방법을 어찌해결 해야 할까요....

    2011/03/16 14:33 [ ADDR : EDIT/ DEL : REPLY ]
    • 카메라 영상에도 관원 효과를 같이 주고 싶으신 것 같습니다. (이게 맞는건지 잘 모르겠네요 ^^) 카메라 프리뷰를 다르게 보여주려면 프리뷰 이미지 데이터 자체를 후처리 후에 SurfaceView에 띄워주는 식으로 해야 제대로 적용이 될 겁니다.

      2011/03/20 23:26 [ ADDR : EDIT/ DEL ]
  13. 퐁듀

    소스파일 그대로 옵티머스원 기기에서 실행시켜보았는데요,
    예기치 못한 오류가 발생했다면서 (즉, 런타임에러..)
    바로 죽어버리네요. 안드로이드사이드에서 어떤 분이 같은 증상에 대해
    넥서스원은 parameters.setPreviewsize(800,480);으로 고정시키면 된다기에
    그렇게도 해보고, 옵티머스원에 맞춰 320, 480로도 해보았는데 죽는건 여전하네요.
    혹시 답변해주실 수 없는지요?ㅜㅜ

    2011/04/01 21:44 [ ADDR : EDIT/ DEL : REPLY ]
    • 로그캣 에러 내용을 확인해보는게 좋을듯 하네요. 단순히 런타임 에러 났다는 사실만으로는 해결방법을 알 수 없습니다 :)

      2011/04/02 10:34 [ ADDR : EDIT/ DEL ]
  14. 해본결과

    //mCamera.setParameters(parameters);
    파라미터를 set할 경우 runtime error가 발생합니다.
    저는 그냥 주석 처리했습니다.

    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): FATAL EXCEPTION: main
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): java.lang.RuntimeException: setParameters failed
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.hardware.Camera.native_setParameters(Native Method)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.hardware.Camera.setParameters(Camera.java:647)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at com.androidhuman.example.CameraPreview.Preview.surfaceChanged(CameraPreview.java:69)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.SurfaceView.updateWindow(SurfaceView.java:538)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.SurfaceView.dispatchDraw(SurfaceView.java:339)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewGroup.drawChild(ViewGroup.java:1638)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.View.draw(View.java:6911)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.widget.FrameLayout.draw(FrameLayout.java:352)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewGroup.drawChild(ViewGroup.java:1640)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1367)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.View.draw(View.java:6911)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.widget.FrameLayout.draw(FrameLayout.java:352)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1848)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewRoot.draw(ViewRoot.java:1407)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewRoot.performTraversals(ViewRoot.java:1163)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.view.ViewRoot.handleMessage(ViewRoot.java:1727)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.os.Handler.dispatchMessage(Handler.java:99)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.os.Looper.loop(Looper.java:123)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at android.app.ActivityThread.main(ActivityThread.java:4627)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at java.lang.reflect.Method.invokeNative(Native Method)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at java.lang.reflect.Method.invoke(Method.java:521)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:870)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
    04-25 13:47:03.481: ERROR/AndroidRuntime(14571): at dalvik.system.NativeStart.main(Native Method)
    04-25 13:47:03.489: WARN/ActivityManager(1715): Force finishing activity com.androidhuman.example.CameraPreview/.CameraPreview

    그리고 중간에 써주신 분처럼 mCamera.release(); 루틴이 들어가야 안정적인 app가 되는 것 같습니다.
    좋은 강좌 감사합니다 ^^

    2011/04/25 13:56 [ ADDR : EDIT/ DEL : REPLY ]
    • 위 예제의 개선된 버전은 책 6장의 예제코드에 포함되어있습니다 :)

      2011/04/25 14:15 [ ADDR : EDIT/ DEL ]
  15. 홍텐

    카메라로 촬영 후 바로 저장하고, 촬영된 사진을 불러와서 이미지뷰에 띄어준 다음 전송버튼을 눌러서 웹서버로 전송하려는 액티비티를 만들고 있습니다. 현제 모든 기능이 정상 작동하나 문제가 하나 있습니다. 바로 이미지의 크기인데요
    애초에 촬영 후 저장된 사진을 불러올 때 썸네일 이미지를 불러오고 그 썸네일 이미지를 웹서버로 보냅니다. 이 부분에서 저는 썸네일 이미지가 아닌 실제 안드로이드 갤러리에 저장된 이미지를 가져와서 이미지뷰에 뿌리고 그걸 웹서버로 전송하고 싶은데 onActivityResult에서 썸네일이 아닌 실제 갤러리에 저장된 이미지를 받을려면 어떻게 해야할까요?

    2011/05/31 12:39 [ ADDR : EDIT/ DEL : REPLY ]
    • 카메라로 사진을 촬영하거나 갤러리에서 이미지를 선택한 경우 인텐트의 데이터(Data)를 통해 이미지의 고유 주소(Uri)를 얻을 수 있습니다. (Intent.getData())

      이를 사용하면 원본 이미지에 접근하는 것이 가능합니다.

      2011/06/05 16:18 [ ADDR : EDIT/ DEL ]
  16. 에서 저는 썸네일 이미지가 아닌 실제 안드로이드 갤러리에 저장된 이미지를 가져와서 이미지뷰에 뿌리고 그걸 웹서버로 전송하고 싶은데 onActivityResult에서 썸네일이 아닌 실제 갤러리에 저장된 이미지를 받을려면 어떻게 해

    2011/06/21 20:00 [ ADDR : EDIT/ DEL : REPLY ]
    • http://developer.android.com/reference/android/provider/MediaStore.Images.Media.html

      참고하세요.

      2011/06/23 02:46 [ ADDR : EDIT/ DEL ]
  17. 유혈

    안녕하세요~ 커니님 !!
    강좌를 잘보고있습니다~
    여쭤보고싶은게 한가지있습니다
    AR기능처럼 카메라 위에 이미지를 띄우고싶은데 레이아웃을 만든다음 불러오면은되는건가요??!!
    또 AR기능은 어떤식으로 구현되는지도 궁금합니다

    2011/07/05 21:03 [ ADDR : EDIT/ DEL : REPLY ]
    • FrameLayout을 사용해서 카메라 프리뷰와 AR 객체를 표시하는 뷰를 겹쳐 표시하면 됩니다 :)

      AR기능은... 유형에 따라 천차만별이여서 딱히 어떤식으로 구현되는지 말씀드리기가 어렵네요.

      2011/07/21 18:46 [ ADDR : EDIT/ DEL ]
  18. 아무거나냐

    커니님 카메라 프리뷰위에 FrameLayout 으로 ImageView 겹치게 해서 보여주고
    사진찍기 눌렀을때 함께저장하고 싶은데 어떻게 해야할까요?
    화면캡쳐기능으로 될까 해봤는데 안되더라구요..

    2011/07/21 13:54 [ ADDR : EDIT/ DEL : REPLY ]
    • 카메라 프리뷰 화면이 표시되는 SurfaceView는 화면 캡쳐를 통해 캡쳐되지 않습니다. 사진을 촬영한 후 그림을 합성하는 방법 등을 사용해야 할 듯 합니다.

      2011/07/21 18:48 [ ADDR : EDIT/ DEL ]
  19. ㅇㄹㅇㄹ

    커니님 궁금한게 잇는데
    카메라 뷰에 만약 프레임레이아웃으로 카메라 뷰 위에 버튼을 하나 만들어노면
    사진 찍엇을때 그 버튼부분이 검게 안나타나게 할 방법이 없을까요 ?
    사진 찍기 전에 autofocus전에 그 버튼을 안보이게 해도
    사진 찍을때의 파일을 보면 검은 부분이 없는데 딱 찍는게 끝나고 찍힌 사진보면 검은 부분이 나타나네요...
    왜이럴까요 ? 레이아웃을 게속 바꿔보면서 해봣는데..

    2011/08/02 23:18 [ ADDR : EDIT/ DEL : REPLY ]
    • 잉???
      그런현상은 처음 들어보네요....

      보통 RelativeLayout을 사용하여 버튼 배치하곤 하는데, 촬영 결과물은 뷰 위에 뭐가 올라가느냐랑은 상관이 없습니다.

      <ViewGroup>
      <SurfaceView>.. </SurfaceView>
      <Button> .. </Button>
      </ViewGroup>

      이런식의 레이아웃이라면 전혀 문제가 없습니다.

      2011/08/03 00:40 [ ADDR : EDIT/ DEL ]
  20. 카메라어플을 구동시키는데, 카메라찍는화면위에 이미지하나를 가져와서 보이게 할수가 있나요??

    2011/09/09 17:20 [ ADDR : EDIT/ DEL : REPLY ]
  21. 강좌 정말 도움되고 재미지게 잘 보았습니다.

    2011/09/14 19:53 [ ADDR : EDIT/ DEL : REPLY ]
  22. 쉼짱

    메일로 문의 드렸는데 아직 못보신거 같아요~!!
    카메라 관련된 앱을 만들고 있는데 질문사항이 있어서요^^

    2011/09/30 01:13 [ ADDR : EDIT/ DEL : REPLY ]
    • 죄송합니다.최근 복학해서 정신이 없네요..ㅠㅠㅠ

      2011/10/07 10:34 [ ADDR : EDIT/ DEL ]
  23. 이재상

    질문 있습니다. 안드로이드 초보라서 허접한 질문인데요 ㅠㅠ
    저기 프리뷰 사이즈를 줄이고싶은데 어떤식으로 해야는지 좀 알려주실수 있을까요?
    파라미터의 사이즈를 적어도 별 달라지는거 없는거 같구요
    사이즈 줄이는것하고 그화면을 원하는 위치에 두는 방법좀 알려주시면 감사하겠습니다.

    2011/11/09 12:45 [ ADDR : EDIT/ DEL : REPLY ]
  24. 김준범

    안녕하세요 커니님
    제가 실시간 영상처리를 해보려고하는데
    open CV를 사용하지 않고 안드로이드 안면인식 API를 써서하려고하는데
    가능할까요?ㅠㅠ 어떤식으로 하면 될까요?ㅠㅠ

    2011/12/03 02:19 [ ADDR : EDIT/ DEL : REPLY ]
  25. 봄날의 곰

    항상 잘 보고있습니다..출처 남기고 퍼갑니다..^^*..

    2012/05/29 13:22 [ ADDR : EDIT/ DEL : REPLY ]
  26. 좋은자료 잘 보았습니다 ^^

    2012/08/14 21:23 [ ADDR : EDIT/ DEL : REPLY ]
  27. 감사

    감사합니다.

    2012/09/04 11:48 [ ADDR : EDIT/ DEL : REPLY ]
  28. 안드로이드 초보..

    앱을 만들고 있는 학생인데요... 카메라 프리뷰를 넣었는데요.. 화면에 그냥 검은 사각형으로만 나와서 어떤 방법을 써보아도... 카메라가 나오지 않아서 질문드립니다.. 저는 사각틀안에 프리뷰를 넣었는데 왜 나오지 않는 것인지 도무지 이해가 되지않습니다..ㅠㅠ

    package exam.androidfirst;

    import java.io.*;
    import java.util.*;

    import android.app.*;
    import android.content.*;
    import android.graphics.drawable.*;
    import android.hardware.*;
    import android.hardware.Camera.Parameters;
    import android.hardware.Camera.Size;
    import android.os.*;
    import android.util.*;
    import android.view.*;
    import android.view.View.OnClickListener;
    import android.widget.*;
    import android.os.CountDownTimer;

    public class Fun1Activity extends Activity {
    MyCameraSurface mSurface;
    Button mShutter;
    TextView mMainText;
    Parameters mParam;

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.i1);

    mSurface = (MyCameraSurface)findViewById(R.id.preview);
    mMainText = (TextView)findViewById(R.id.mainvalue);

    new CountDownTimer(20000,1000){
    public void onTick(long millisUntilFinished) { //<타이머가 종료될때까지 동작하는 함수>
    mMainText.setText("남은 시간 : " + millisUntilFinished / 1000);
    //mParam.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    }
    public void onFinish() { //<타이머가 종료될때 실행 동작하는 함수>
    Intent intent = new Intent(Fun1Activity.this, Fun1_1Activity.class);
    startActivity(intent);
    }
    }.start();


    Button pre_button = (Button)findViewById(R.id.pre_button);
    Drawable a4 = pre_button.getBackground();
    a4.setAlpha(400);


    pre_button.setOnClickListener(
    new OnClickListener(){
    public void onClick(View v){
    Log.i("Multi Activity", "Button click is occured..";);
    Intent intent = new Intent(Fun1Activity.this, MainActivity.class);
    startActivity(intent);
    }
    }
    );
    }

    }
    class MyCameraSurface extends SurfaceView implements SurfaceHolder.Callback {
    SurfaceHolder mHolder;
    Camera mCamera;

    public MyCameraSurface(Context context, AttributeSet attrs) {
    super(context, attrs);
    mHolder = getHolder();
    mHolder.addCallback(this);
    mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    // 표면 생성시 카메라 오픈하고 미리보기 설정
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
    mCamera = Camera.open();
    try {
    mCamera.setPreviewDisplay(mHolder);
    } catch (IOException e) {
    mCamera.release();
    mCamera = null;
    }
    }

    // 표면 파괴시 카메라도 파괴한다.
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
    if (mCamera != null) {
    mCamera.stopPreview();
    mCamera.release();
    mCamera = null;
    }
    }

    // 표면의 크기가 결정될 때 최적의 미리보기 크기를 구해 설정한다.
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
    Camera.Parameters params = mCamera.getParameters();
    List<Size> arSize = params.getSupportedPreviewSizes();
    if (arSize == null) {
    params.setPreviewSize(width, height);
    } else {
    int diff = 10000;
    Size opti = null;
    for (Size s : arSize) {
    if (Math.abs(s.height - height) < diff) {
    diff = Math.abs(s.height - height);
    opti = s;

    }
    }
    params.setPreviewSize(opti.width, opti.height);
    }
    mCamera.setParameters(params);
    mCamera.startPreview();
    }
    }


    이것은 xml입니다.
    <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/home_root"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#111111">

    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <TextView
    android:id="@+id/mainvalue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textSize="20dp" />

    </LinearLayout>

    <LinearLayout
    android:layout_width="300dip"
    android:layout_height="0dip">

    <exam.androidfirst.MyCameraSurface
    android:id="@+id/preview"
    android:layout_marginLeft="200dip"
    android:layout_width="100dip"
    android:layout_height="100dip"
    /></LinearLayout>

    <LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    android:background="#00000000" >

    <ImageView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />
    </LinearLayout>


    <LinearLayout

    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    </LinearLayout>

    <Button
    android:id="@+id/pre_button"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="360dip"
    android:background="@drawable/imgbutton2"
    android:text="@string/PrevString"
    android:textColor="#ffDDA0DD"
    android:textSize="20dp" />

    </LinearLayout>

    2012/11/29 06:37 [ ADDR : EDIT/ DEL : REPLY ]
  29. 독학생

    고맙습니다!!!

    2013/06/08 15:27 [ ADDR : EDIT/ DEL : REPLY ]