Notice
Recent Posts
Recent Comments
Link
관리 메뉴

설.현.아빠

[Camera] Preview & Capture 구현 본문

안드로이드/Device & Sensor

[Camera] Preview & Capture 구현

설.현.아빠 2011. 2. 11. 09:51




 

<?xml version="1.0" encoding="utf-8"?>

 

<-- main.xml -->


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<Button android:text="Capture" android:id="@+id/mainWallpaper" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
<FrameLayout android:id="@+id/mainFrameLayout01" android:layout_width="wrap_content" android:layout_height="wrap_content"></FrameLayout>
</LinearLayout>

 

<?xml version="1.0" encoding="utf-8"?>

 

<-- AndroidManifest.xml -->


<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="lee.android.Main"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
    <uses-sdk android:minSdkVersion="8" />
 <uses-permission android:name="android.permission.SET_WALLPAPER"></uses-permission>
 <uses-permission android:name="android.permission.CAMERA"></uses-permission>
</manifest>

 

 

//MainActivity.java

 

package lee.android.Main;

import java.io.ByteArrayInputStream;

import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;

public class MainActivity extends Activity {
    public CamView _camView=null;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        FrameLayout _frameLayout = (FrameLayout)findViewById(R.id.mainFrameLayout01);
        _camView = new CamView(this);
        _frameLayout.addView(_camView);
        
        Button wallpaper = (Button)findViewById(R.id.mainWallpaper);
        wallpaper.setOnClickListener(on_PaperClick);
    }
    
    private View.OnClickListener on_PaperClick = new View.OnClickListener() {
     // Camera에 있는 Image를 Capture해서 WallPaper로 setting해 준다.
     @Override
  public void onClick(View v) {
   _camView.Capture(new Camera.PictureCallback() {
    
    @Override
    public void onPictureTaken(byte[] data, Camera camera) {
     ByteArrayInputStream bais = new ByteArrayInputStream(data);  
     try {
      setWallpaper(bais);
     } catch (Exception e) {
      // TODO: handle exception
     }
    }
   });
   
  }
 };

}

 

// CamView.java

 

package lee.android.Main;

import android.content.Context;
import android.hardware.Camera;
import android.util.AttributeSet;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CamView extends SurfaceView implements SurfaceHolder.Callback{
 // SurfaceView를 사용하기 위해서 SurfaceHolder.Callback을 구현하는 클래스를 생성함.
 // SurfaceHolder.Callback을 설정함으로써 Surface가 생성/소명되었음을 알 수 있다.
 private SurfaceHolder _holder; // 이 객체를 통해 실제로 Contents가 표시되는 영역인 Surface를 관리할 수 있다.
 private Camera _camera=null; // SurfaceView에 Camera에서 받은 영상을 표시하기 위한 Camera객체 추가.
 
 public CamView(Context context) {
  super(context);
  
  _holder = getHolder();
  // SurfaceView의 SurfaceHolder Instance를 연결해 준다.
  // _holder객체를 통해 이 SurfaceView의 Surface에 접근할 수 있게 된다.
  
  _holder.addCallback(this);
  // SurfaceHolder와 SurfaceView를 연결시켜주는 과정.
  // Surface가 변경됨을 SurfaceHolder(_holder)를 거쳐 최종적으로 SurfaceView에서도 알 수 있다.
  
  _holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
  // Camera Preview는 별도의 버퍼가 없어도 되므로 위와 같이 옵션을 설정한다.
 }

 public CamView(Context context, AttributeSet attrs) {
  super(context, attrs);
  // TODO Auto-generated constructor stub
 }

 public CamView(Context context, AttributeSet attrs, int defStyle) {
  super(context, attrs, defStyle);
  // TODO Auto-generated constructor stub
 }
 
 // SurfaceHolder.Callback에 있는 Interface Methods
 public void surfaceCreated (SurfaceHolder holder) {
  // Surface가 생성되었다면, Camera의 Instance를 받아온 후 Camera의 Priview를 표시할 위치를 설정한다.
  _camera = Camera.open(); // Camera로 부터 객체를 받아옴.
  try {
   _camera.setPreviewDisplay(_holder); // Camera로 부터 받은 Preview영상을 어디에 표시할지 지정.
  } catch (Exception e) {
   // Preview화면을 제대로 표시하지 못했다면 Camera의 자원을 반환한다.
   _camera.release();
   _camera=null;
   // TODO: handle exception
  }
 }
 public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {
  // 표시할 영역의 크기를 알았으므로 해당 크기로 Preview를 시작한다.
  Camera.Parameters _params = _camera.getParameters(); // Camera의 여러 설정값들을 담고 있는 parameters를 받아옴.
  _params.setPreviewSize(width, height); // Preview의 크기 지정.
  _camera.setParameters(_params); // Preview의 크기 지정한 값을 넘겨줌으로써 Preview 영상을 표시할 영역의 크기 설정.
  _camera.startPreview(); // 최종적으로 Camera Preview 영상 표시!!!
 }
 
 public boolean Capture(Camera.PictureCallback jpegHandler) {
  if(_camera!=null) {
   _camera.takePicture(null, null, jpegHandler);
   return true;
  }
  else {
   return false;
  }
 }
 
 public void surfaceDestroyed (SurfaceHolder holder) {
  // 다른 화면으로 돌아가면, Surface가 소멸된다. 따라서 Camera의 Preview도 중지해야함.
  // Camera는 공유할 수 있는 자원이 아니기에 사용하지 않을 경우 -Activity가 일시정지 상태가 된 경우 등 -
  // 자원을 반환해야함.
  _camera.stopPreview();
  _camera = null;
 }
}

 

 

 

 

Comments