사용자 지정 카메라(1)

25846 단어 사용자 정의

5.0 이전 릴리즈에서 카메라를 사용자화하는 절차는 다음과 같습니다.


하나, 사용자 정의 카메라를 만드는 절차


1. 카메라 찾기 및 사용 권한 얻기


카메라의 존재를 감지하고 권한을 얻습니다
카메라 장치 코드 확인
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
        //      
        return true;
    } else {
        //       
        return false;
    }

카메라 사용 가능한 코드 확인
Camera c = null;
    try {
        c = Camera.open(); //          
    }
    catch (Exception e){
        //            
    }

2. 미리 보기 보기 클래스 만들기


클래스는 SurfaceView의 하위 클래스여야 합니다.
사용자 정의 보기 클래스로
그 주요 업무는 서로 다른 이벤트 내에서 전송된 Camera 실례를 통해 미리 보기 보기(Preview)를 제어하는 것이다.
구체적인 API 데모 코드는 다음과 같습니다.
/** A basic Camera preview class */
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreview(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // Install a SurfaceHolder.Callback so we get notified when the
        // underlying surface is created and destroyed.
        mHolder = getHolder();
        mHolder.addCallback(this);
        // deprecated setting, but required on Android versions prior to 3.0
        mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        // The Surface has been created, now tell the camera where to draw the preview.
        try {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        } catch (IOException e) {
            Log.d(TAG, "Error setting camera preview: " + e.getMessage());
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // empty. Take care of releasing the Camera preview in your activity.
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        //// Make sure to stop the preview before resizing or reformatting it.

        if (mHolder.getSurface() == null){
          // preview surface does not exist
          return;
        }

        // stop preview before making changes
        try {
            mCamera.stopPreview();
        } catch (Exception e){
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d(TAG, "Error starting camera preview: " + e.getMessage());
        }
    }
}

3. 미리 보기 레이아웃 만들기


비교적 간단한 레이아웃으로 나중에 카메라 미리보기를 표시하는 SurfaceView는 코드를 통해 FrameLayout에 추가됩니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
  <FrameLayout
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="1"
    />

  <Button
    android:id="@+id/button_capture"
    android:text="Capture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    />
</LinearLayout>

이에 대응하는 Activity의 주요 코드는 다음과 같습니다.
public class CameraActivity extends Activity {

    private Camera mCamera;
    private CameraPreview mPreview;

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

        //   Camera   
        mCamera = Camera.open();

        // Activity  Preview  SurfaceView
        mPreview = new CameraPreview(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mPreview);
    }
}

 

4. 촬영 동작을 감청


버튼이 동작을 감청하고 초점을 맞추기 시작한다
구체적인 코드 구현은 일반 감청과 마찬가지로 초점을 맞추면camera를 사용할 수 있다.autoFocus(autoFocusCallBack);
autoFocusCallBack은 AutoFocusCallback의 실례로 초점 맞추기가 끝난 후의 조작을 되돌리는 데 주로 사용된다.
예를 들어 Camera를 통해서.takePicture(shutter, PictureCallback, PictureCallback) 캡처 이미지

5. 사진 캡처 및 저장


Camera를 통해takePicture(shutter, PictureCallback, PictureCallback) 이미지를 캡처한 후 저장해야 합니다.
private PictureCallback mPicture = new PictureCallback() {

    @Override
    public void onPictureTaken(byte[] data, Camera camera) {

        File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
        if (pictureFile == null){
            Log.d(TAG, "Error creating media file, check storage permissions: " +
                e.getMessage());
            return;
        }

        try {
            FileOutputStream fos = new FileOutputStream(pictureFile);
            fos.write(data);
            fos.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, "File not found: " + e.getMessage());
        } catch (IOException e) {
            Log.d(TAG, "Error accessing file: " + e.getMessage());
        }
    }
};

이상은 공식 API의 데모로 onPictureTaken 방법을 통해 포획된 이미지 데이터를 획득하여 참고할 수 있습니다.

6. 카메라 리소스 여유 확보


이전의surfaceDestroyed에서camera를 통과할 수 있습니다.release는 다른 응용 프로그램의 사용에 영향을 주지 않도록 카메라 자원을 방출합니다
다음은 자신이 쓴 데모입니다. 그림이 간단하고 많이 절약되었고 구조도 어지럽습니다. 그러나 기본적인 사진 기능은 이미 실현되었습니다.
package com.rw.demo;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;


public class CameraDemo extends Activity {
    private SurfaceView cameraSurface;
    private SurfaceHolder myHolder;
    private boolean isPreview=false;
    Camera camera;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        
        setContentView(R.layout.camera_layout);
        
        getView();
        
        //      
        myHolder=cameraSurface.getHolder();
        myHolder.addCallback(new Callback() {
            
            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                
            }
            
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                try {
                    CameraDemo.this.initCamera(holder);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            
            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width,
                    int height) {
                
            }
        });
    }

    /**
     *      
     * @param holder
     * @throws IOException 
     */
    @SuppressWarnings("deprecation")
    protected void initCamera(SurfaceHolder holder) throws IOException {
        
            if(!isPreview)
                camera=Camera.open(1);
            camera.setDisplayOrientation(90);
        if(camera!=null && !isPreview){
            
            camera.setPreviewDisplay(holder);
            
            camera.startPreview();

            isPreview=true;
        }
    }

    /**
     *       
     */
    private void getView() {
        cameraSurface=(SurfaceView) findViewById(R.id.camera_surface_id);
    }
    /**
     *     
     * @param v
     */
    public void takePhoto(View v){
        if(camera!=null){
            Log.i("CameraDemo","     !");
            camera.autoFocus(autoFocusCallBack);
        }
    }
    //            
    AutoFocusCallback autoFocusCallBack =new AutoFocusCallback() {
        
        @Override
        public void onAutoFocus(boolean success, Camera camera) {
            if(success){
                camera.takePicture(new ShutterCallback() {
                    
                    @Override
                    public void onShutter() {
                        
                    }
                }, new PictureCallback(){

                    @Override
                    public void onPictureTaken(byte[] data, Camera camera) {
                        
                    }
                    
                }, jpeg);
            }
        }
    };
    //           
    PictureCallback jpeg=new PictureCallback() {
        
        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            //           
            final Bitmap bm=BitmapFactory.decodeByteArray(data,0, data.length);
            
            File file=new File(Environment.getExternalStorageDirectory(),"testPicture.jpg");
            
            FileOutputStream outStream =null;
            
            try {
                outStream=new FileOutputStream(file);
                bm.compress(CompressFormat.JPEG, 100, outStream);
                outStream.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            camera.stopPreview();
            camera.startPreview();
            isPreview=true;
            
        }
    };
    //       
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(camera!=null){
            camera.release();
        }
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
    }
    
    
    
}

좋은 웹페이지 즐겨찾기