메뉴 건너뛰기

조회 수 14218 추천 수 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
번호 제목 날짜 조회 수
257 Activity Data Transfor/ 액티비티 이동간에 데이터 전송하기 file 2016.06.07 7676
256 Activity Switching / 안드로이드 액티비티 전환 / 화면 전환 file 2016.06.07 8311
255 Android Login and Registration with PHP, MySQL and SQLite file 2015.07.16 14178
254 Android Navigation Drawer API 공개! 디자인 가이드 살펴보기 file 2015.07.29 8141
253 Android Push GCM 서버 구성 하기(3) file 2015.12.14 6388
252 Android Push GCM 프로젝트 앱 적용 하기(2) file 2016.03.18 8953
251 android SMS 리시버 2015.06.29 6871
250 Android Studio에서 SQLCipher 라이브러리 추가 방법 file 2018.10.02 1776
249 Android TIP] strings.xml 에서 특수문자 사용하기 2015.12.15 6629
248 Android 간단한 회원 가입 폼 만들기 for Mac (PHPMyAdmin 이용) file 2015.07.10 10508
247 Android 와 JSP 간 파라미터 암복호화 (1) file 2016.05.26 7474
246 Android 와 JSP 간 파라미터 암복호화 (2) 2016.05.26 7735
245 Android 와 JSP 간 파라미터 암복호화 (3) file 2016.05.26 8088
244 android.support.v4.content.FileProvider not found file 2020.12.14 308
243 AndroidManifest에 선언한 메타데이터(meta-data) 가져오기 2016.06.10 9313
242 Android] Fragment 내부의adapter에서 startActivity 하기 2015.12.15 6487
241 Android] 안드로이드 홈 디렉토리 알아내기 2015.12.15 6895
240 Apk manager 이용해 Decompile (디컴파일) 하기 file 2021.03.16 1622
239 App 실행 file 2021.03.31 244
238 CSS3 Rounded Corner, 그림자 효과 사용하기 file 2014.09.04 6760
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

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

© k2s0o1d4e0s2i1g5n. All Rights Reserved