2012年7月13日 星期五

Android Taking Snapshot




  • Set Preview Callback
    camera.setPreviewCallback(new Camera.PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera camera) {
    ...
        }
    }

  • Compress Raw Data to Jpeg Format


    Camera.Parameters parameters = camera.getParameters();
    Size size = parameters.getPreviewSize();
    YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
    Rect rect = new Rect();
    rect.bottom = size.height;
    rect.top = 0;
    rect.left = 0;
    rect.right = size.width;
    image.compressToJpeg(rect, 100, compressedData);
  • Setup Camera Surface 

    camerasurface = new CameraSurface(this);
    cameraholder.addView(camerasurface, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));

  • Sample Code for Android Taking Snapshot

package zachary.samples.camera;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;

public class TakingShotActivity extends Activity implements OnClickListener {
    private final String mTAG = "TakingShotActivity";
    private FrameLayout cameraholder = null;
    private CameraSurface camerasurface = null;  
  
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.i(mTAG, "onCreate()");
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.main);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        cameraholder = (FrameLayout)findViewById(R.id.camera_preview);
        cameraholder.setOnClickListener(this);
        setup();
    }

    @Override
    protected void onDestroy() {
       Log.i(mTAG, "onDestroy()");
       camerasurface.surfaceDestroyed(cameraholder);
       camerasurface = null;
       cameraholder.removeAllViews();
       cameraholder = null;
       super.onDestroy();
    }

    private void setup() {
        Log.i(mTAG, "setup()");
        camerasurface = new CameraSurface(this);
        cameraholder.addView(camerasurface, new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
    }

    @Override
    public void onClick(View v) {
        switch(v.getId()) {
        case R.id.camera_preview: {
            camerasurface.takePicture();
            break;
        }};  
   }
}   


package zachary.samples.camera;

import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import android.content.Context;
import android.graphics.ImageFormat;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Size;
import android.os.Build;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.FrameLayout;

public class CameraSurface extends SurfaceView implements SurfaceHolder.Callback {
    private final String mTAG = "CameraSurface";
    private Camera camera = null;
    private SurfaceHolder holder = null;
    private int cameraOrientation = 0;
    private boolean previewing = false;
    private boolean takeShot = false;
   
    public CameraSurface(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initialize(context);
    }

    public CameraSurface(Context context) {
        super(context);
        initialize(context);
    }

    public CameraSurface(Context context, AttributeSet attrs) {
        super(context, attrs);
        initialize(context);
    }

    public void startPreview() {
        Log.i(mTAG, "startPreview()");
        camera.startPreview();
    }
   
    public void stopPreview() {
        Log.i(mTAG, "stopPreview()");
        camera.stopPreview();
    }

    public void takePicture() {
        Log.i(mTAG, "takePicture()");
        camera.autoFocus(new AutoFocusCallback() {
            @Override
            public void onAutoFocus(boolean success, Camera camera) {
               Log.i(mTAG, "onAutoFocus()");
               if (success) {
                    takeShot = true;
               }
            }
        });
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {
        Log.i(mTAG, "surfaceChanged()");
        if (previewing) {
            if (camera != null)
                camera.stopPreview();
            previewing = false;
        }
        if (camera != null) {
            camera.startPreview();
            camera.setPreviewCallback(new Camera.PreviewCallback() {
                public void onPreviewFrame(byte[] data, Camera camera) {
                    Log.d(mTAG, "onPreviewFrame called at: " + System.currentTimeMillis()); 
                    CameraSurface.this.invalidate();
                    if (takeShot) {
                        try {
                            String file;
                            if (Build.BRAND.equalsIgnoreCase("samsung"))
                               file = String.format(getContext().getExternalFilesDir(null).getPath().substring(4) + "/%d.jpg", System.currentTimeMillis());
                            else if (Build.BRAND.equalsIgnoreCase("htc_asia_tw"))
                               file = String.format(getContext().getExternalFilesDir(null).getPath().toString() + "/%d.jpg", System.currentTimeMillis());
                            else
                               file = String.format(getContext().getExternalFilesDir(null).getPath().toString() + "/%d.jpg", System.currentTimeMillis());
                            FileOutputStream fileoutputstream = new FileOutputStream(file);
                            Camera.Parameters parameters = camera.getParameters();
                            Size size = parameters.getPreviewSize();
                            YuvImage image = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
                            Rect rect = new Rect();
                            rect.bottom = size.height;
                            rect.top = 0;
                            rect.left = 0;
                            rect.right = size.width;
                            ByteArrayOutputStream compressedData = new ByteArrayOutputStream();
                            image.compressToJpeg(rect, 100, compressedData);
                            fileoutputstream.write(compressedData.toByteArray());
                            fileoutputstream.close();
                        }
                        catch(Exception e) {
                            e.printStackTrace();
                        }
                        takeShot = false;                     
                    }
                }
            });
            previewing = true;
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
       Log.i(mTAG, "surfaceCreated()");
       CameraInfo camerainfo = new Camera.CameraInfo();
        for (int index = 0; index < Camera.getNumberOfCameras(); index++) {
           Camera.getCameraInfo(index, camerainfo);
           if (camerainfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
              try {
                  camera = Camera.open(index);
              } catch (RuntimeException e) {
                  e.printStackTrace();
              }
              cameraOrientation = (camerainfo.orientation + 0) % 360;
              cameraOrientation = (360 - cameraOrientation);
              camera.setDisplayOrientation(cameraOrientation);
              Camera.Parameters cameraparameters = camera.getParameters();
              cameraparameters.setRotation(camerainfo.orientation);
              camera.setParameters(cameraparameters);
           }
        }
       try {
          camera.setPreviewDisplay(holder);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void surfaceDestroyed(FrameLayout cameraholder) {
        Log.i(mTAG, "surfaceDestroy(FrameLayout)");
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.release();
            camera = null;
        }
        previewing = false;
    }

    private void initialize(Context context) {
        Log.i(mTAG, "initialize()");
        holder = getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {     
        Log.i(mTAG, "surfaceDestroy(SurfaceHolder)");
    }
}

沒有留言:

張貼留言