메뉴 건너뛰기

조회 수 14236 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄

안녕하세요. LIM 이에요.

안드로이드 TextureView를 이용한 카메라 Preview 영상 출력과 Preview영상의 좌우반전, 그리고 사진찍기에 대해 알아보겠어요.



보통 안드로이드 카메라를 검색하면 SurfaceView를 이용한 예제가 많이 검색될 것입니다.

하지만 SurfaceView를 사용하면 알파, 확대, 뒤집기 등이 제한적이에요.

안드로이드는 Android API 14부터 TextureView를 지원하는데요, SurfaceView의 단점을 보완하여 나왔다고 볼 수 있습니다.

국내 블로그에는 예제가 많지않아 해외구글링을 통해 구현했는데, 많은 분께 공유하고자 소스를 올립니다.



(1) Layout.XML에 TextureView 추가


  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent"
  5.     android:layout_marginRight="2dp"
  6.     android:layout_marginTop="2dp" >
  7.  
  8.     <TextureView
  9.         android:id="@+id/fl"
  10.         android:layout_width="fill_parent"
  11.         android:layout_height="fill_parent"
  12.         android:layout_alignParentLeft="true"
  13.         android:layout_alignParentTop="true" />
  14.  
  15.     <ImageButton
  16.         android:id="@+id/btCapture"
  17.         android:layout_width="80dp"
  18.         android:layout_height="wrap_content"
  19.         android:layout_alignParentBottom="true"
  20.         android:layout_centerHorizontal="true"
  21.         android:background="@drawable/round_box"
  22.         android:padding="5dp"
  23.         android:src="@drawable/icon_camera" />
  24.  
  25. </RelativeLayout>

 


(2) Activity.java에 리스너 상속 및 콜백함수 오버라이드


  1. public class MainActivity extends Activity implements TextureView.SurfaceTextureListener {
  2. ...
  3. }
  1.     @Override
  2.     public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height){
  3.         mCamera = Camera.open(CAMERA_ID);
  4.         Matrix matrix = new Matrix();
  5.         matrix.setScale(-1, 1);
  6.         matrix.postTranslate(width, 0);
  7.         mTextureView.setTransform(matrix);
  8.        
  9.         Camera.Parameters parameters = mCamera.getParameters();
  10.         parameters.setPreviewSize(resWidth, resHeight);
  11.         parameters.setPictureSize(resWidth, resHeight);
  12.         mCamera.setParameters(parameters);
  13.        
  14.         try{
  15.             mCamera.setPreviewTexture(surfaceTexture);
  16.             mCamera.startPreview();
  17.         }catch(IOException ioe){
  18.             Log.e("camera-reverse", ioe.getMessage());
  19.         }
  20.     }
  21.    
  22.     @Override
  23.     public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
  24.  
  25.     }
  26.    
  27.     @Override
  28.     public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
  29.         if (null != mCamera) {
  30.             mCamera.stopPreview();
  31.             mCamera.release();
  32.         }
  33.         return true;
  34.     }
  35.    
  36.     @Override
  37.     public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
  38.  
  39.     }

 


(3) TextureView 리스너 및 버튼 리스너 등록


  1.     private void init(){
  2.         setContentView(R.layout.activity_main);
  3.         mTextureView = (TextureView)findViewById(R.id.fl);
  4.        
  5.         mTextureView.setSurfaceTextureListener(this);
  6.        
  7.         ImageButton btCapture = (ImageButton) this.findViewById(R.id.btCapture);
  8.  
  9.         btCapture.setOnClickListener(new View.OnClickListener() {
  10.             @Override
  11.             public void onClick(View v) {
  12.                 mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
  13.             }
  14.         });
  15.     }



(4) takePicture 콜백함수 구현


  1.     ShutterCallback shutterCallback = new ShutterCallback(){
  2.         public void onShutter(){
  3.             Log.e("shutterCallback", "shutterCallback");
  4.         }
  5.     };
  6.    
  7.     PictureCallback rawCallback = new PictureCallback(){
  8.         public void onPictureTaken(byte[] data, Camera camera){
  9.             Log.e("rawCallback", "rawCallback");
  10.         }
  11.     };
  12.    
  13.     PictureCallback jpegCallback = new PictureCallback(){
  14.         public void onPictureTaken(byte[] data, Camera camera){
  15.             Log.e("jpegCallback", "jpegCallback");
  16.            
  17.             Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
  18.  
  19.             try {
  20.  
  21.                 File dir = new File("/path");
  22.                 dir.mkdirs();
  23.  
  24.                 File outFile = new File(dir, "test.jpg");
  25.  
  26.                 FileOutputStream outStream = new FileOutputStream(outFile);
  27.                 picture.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
  28.  
  29.                 outStream.flush();
  30.                 outStream.close();
  31.  
  32.                 picture.recycle();
  33.  
  34.             } catch (FileNotFoundException e) {
  35.                 e.printStackTrace();
  36.             } catch (IOException e) {
  37.                 e.printStackTrace();
  38.             } finally {
  39.             }
  40.         }
  41.     };

 


(5) 전체소스


  1. public class MainActivity extends Activity implements TextureView.SurfaceTextureListener {
  2.  
  3.     private int CAMERA_ID = 0;
  4.     private int cameraNum;
  5.     private TextureView mTextureView;
  6.     private Camera mCamera;
  7.  
  8.     private final int resWidth = 1280;
  9.     private final int resHeight = 720;
  10.    
  11.     @Override
  12.     protected void onCreate(Bundle savedInstanceState) {
  13.         super.onCreate(savedInstanceState);
  14.        
  15.         cameraNum = Camera.getNumberOfCameras();
  16.         if(cameraNum == 0){
  17.             Toast.makeText(MainActivity.this, "there is no camera", Toast.LENGTH_LONG).show();
  18.             finish();
  19.         }else if(cameraNum >= 2){
  20.             CAMERA_ID = 1;
  21.         }
  22.        
  23.         init();
  24.     }
  25.    
  26.     @Override
  27.     public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int width, int height){
  28.         mCamera = Camera.open(CAMERA_ID);
  29.         Matrix matrix = new Matrix();
  30.         matrix.setScale(-1, 1);
  31.         matrix.postTranslate(width, 0);
  32.         mTextureView.setTransform(matrix);
  33.        
  34.         Camera.Parameters parameters = mCamera.getParameters();
  35.         parameters.setPreviewSize(resWidth, resHeight);
  36.         parameters.setPictureSize(resWidth, resHeight);
  37.         mCamera.setParameters(parameters);
  38.        
  39.         try{
  40.             mCamera.setPreviewTexture(surfaceTexture);
  41.             mCamera.startPreview();
  42.         }catch(IOException ioe){
  43.             Log.e("camera-reverse", ioe.getMessage());
  44.         }
  45.     }
  46.    
  47.     @Override
  48.     public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) {
  49.  
  50.     }
  51.    
  52.     @Override
  53.     public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) {
  54.         if (null != mCamera) {
  55.             mCamera.stopPreview();
  56.             mCamera.release();
  57.         }
  58.         return true;
  59.     }
  60.    
  61.     @Override
  62.     public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) {
  63.  
  64.     }
  65.    
  66.     public void onPause() {
  67.         super.onPause();
  68.         releaseCamera();
  69.     }
  70.    
  71.     private void releaseCamera() {
  72.         if (mCamera != null) {
  73.              mCamera.setPreviewCallback(null);
  74.              mCamera.release();
  75.              mCamera = null;
  76.         }
  77.     }
  78.    
  79.     private void init(){
  80.         setContentView(R.layout.activity_main);
  81.         mTextureView = (TextureView)findViewById(R.id.fl);
  82.        
  83.         mTextureView.setSurfaceTextureListener(this);
  84.        
  85.         ImageButton btCapture = (ImageButton) this.findViewById(R.id.btCapture);
  86.  
  87.         btCapture.setOnClickListener(new View.OnClickListener() {
  88.             @Override
  89.             public void onClick(View v) {
  90.                 mCamera.takePicture(shutterCallback, rawCallback, jpegCallback);
  91.             }
  92.         });
  93.     }
  94.    
  95.     ShutterCallback shutterCallback = new ShutterCallback(){
  96.         public void onShutter(){
  97.             Log.e("shutterCallback", "shutterCallback");
  98.         }
  99.     };
  100.    
  101.     PictureCallback rawCallback = new PictureCallback(){
  102.         public void onPictureTaken(byte[] data, Camera camera){
  103.             Log.e("rawCallback", "rawCallback");
  104.         }
  105.     };
  106.    
  107.     PictureCallback jpegCallback = new PictureCallback(){
  108.         public void onPictureTaken(byte[] data, Camera camera){
  109.             Log.e("jpegCallback", "jpegCallback");
  110.            
  111.             Bitmap picture = BitmapFactory.decodeByteArray(data, 0, data.length);
  112.  
  113.             try {
  114.  
  115.                 File dir = new File("/path");
  116.                 dir.mkdirs();
  117.  
  118.                 File outFile = new File(dir, "test.jpg");
  119.  
  120.                 FileOutputStream outStream = new FileOutputStream(outFile);
  121.                 picture.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
  122.  
  123.                 outStream.flush();
  124.                 outStream.close();
  125.  
  126.                 picture.recycle();
  127.  
  128.             } catch (FileNotFoundException e) {
  129.                 e.printStackTrace();
  130.             } catch (IOException e) {
  131.                 e.printStackTrace();
  132.             } finally {
  133.             }
  134.         }
  135.     };
  136.  
  137.  
  138.         @Override
  139.         public boolean onCreateOptionsMenu(Menu menu) {
  140.             getMenuInflater().inflate(R.menu.main, menu);
  141.             return true;
  142.         }
  143.  
  144.         @Override
  145.         public boolean onOptionsItemSelected(MenuItem item) {
  146.             int id = item.getItemId();
  147.             if (id == R.id.action_settings) {
  148.                 return true;
  149.             }
  150.             return super.onOptionsItemSelected(item);
  151.         }
  152. }

List of Articles
번호 제목 날짜 조회 수
157 [안드로이드] 뷰(View)의 너비와 높이 지정하기 file 2015.07.17 7140
156 [안드로이드] 뷰(View)에 여백넣기 file 2015.07.17 7230
155 [안드로이드] 버튼 이벤트 처리하기 file 2015.07.17 7030
154 안드로이드 webview (웹뷰) 개발 #1 - 웹사이트를 어플로 만들어 보자! file 2015.07.17 8911
153 안드로이드 webview (웹뷰) 개발 #2 - 파일 첨부 및 플러그인 적용하기 file 2015.07.17 8295
152 안드로이드 webview (웹뷰) 개발 #3 - 초기 로딩화면 (splash) 띄우기 + 아이콘 적용하기 file 2015.07.17 8697
151 안드로이드 webview (웹뷰) 개발 #4 - 멀티터치 ( 확대 / 축소 ) 적용 file 2015.07.17 7552
150 안드로이드 ( Android ) APK 파일 생성하기 file 2015.07.17 7311
149 [안드로이드] 페이스북 같은 슬라이드 메뉴 만들기 file 2015.07.21 8203
148 [안드로이드] 화면추가 버튼 리스너 file 2015.07.22 7681
147 안드로이드 스튜디오 gradle error 해결 2015.07.23 6683
146 안드로이드 팝업창 만들기(xml 내용 집어넣기) file 2015.07.23 9285
145 블루투스(Bluetooth) 통신에 대해 알아보자 file 2015.07.26 14049
144 블루투스 및 비콘 관련 정리 2015.07.26 10828
143 안드로이트 비콘 스캐닝시 고려 사항 2015.07.26 6663
142 폰갭 비콘 디텍팅 안될 때 (기본적인건 다 되있어야됨) 2015.07.26 6529
141 안드로이드 종료 취소 다이얼로그 코드 2015.07.26 6389
140 안드로이드 로딩화면 샘플 file 2015.07.26 7576
139 안드로이드 채팅 소스 샘플 file 2015.07.26 10088
138 화면 전환해도 데이터 유지 예제 2015.07.26 9204
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved