从SurfaceView捕获照片

时间:2015-07-25 12:19:06

标签: android android-camera surfaceview

我正在尝试从SurfaceView自定义相机捕获图像。我已经设置了初始代码,但我不知道如何调用'拍照'方法,以便我可以在表面上看到预览。

目前此代码实时显示预览。我需要拍照并访问byte []数组

请帮我填写代码:

    private SurfaceView mSurfaceView;
    private SurfaceHolder mSurfaceHolder;
    private Camera mCamera;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);


        captureImage = (ImageButton) findViewById(R.id.captureImage);
        mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);

        captureImage.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {

                  //this button press should take the picture

            }
        });

        mSurfaceView.getHolder().addCallback(this);
        mSurfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        mCamera = Camera.open();
    }

@Override
    public void onPause() {
        super.onPause();
        mCamera.stopPreview();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mCamera.release();
    }


    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        try {
            mCamera.setPreviewDisplay(mSurfaceView.getHolder());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Camera.Parameters params = mCamera.getParameters();
        List<Camera.Size> sizes = params.getSupportedPreviewSizes();
        Camera.Size selected = sizes.get(0);
        params.setPreviewSize(selected.width,selected.height);
        mCamera.setParameters(params);

        mCamera.setDisplayOrientation(90);
        mCamera.startPreview();

    }


    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCamera.stopPreview();
        mCamera.release();
        mCamera = null;

    }

我需要获取bytes []数据,以便我可以将图像转换为base64字符串。如何使用上面的代码调用必要的方法来拍照?

1 个答案:

答案 0 :(得分:2)

在我的例子中检查“jpegCallback”:

public class CameraActivity extends ActionBarActivity implements SurfaceHolder.Callback {
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;

PictureCallback jpegCallback;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_camera);

    surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
    surfaceHolder = surfaceView.getHolder();

    // Install a SurfaceHolder.Callback so we get notified when the
    // underlying surface is created and destroyed.
    surfaceHolder.addCallback(this);

    // deprecated setting, but required on Android versions prior to 3.0
    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    jpegCallback = new PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            FileOutputStream outStream = null;
            try {
                outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));
                outStream.write(data);
                outStream.close();
                Log.d("Log", "onPictureTaken - wrote bytes: " + data.length);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
            }
            Toast.makeText(getApplicationContext(), "Picture Saved", 2000).show();
            refreshCamera();
        }
    };
}

public void captureImage(View v) throws IOException {
    //take the picture
    camera.takePicture(null, null, jpegCallback);
}


@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
    try {
        // open the camera
        camera = Camera.open();
    } catch (RuntimeException e) {
        // check for exceptions
        System.err.println(e);
        return;
    }
    Camera.Parameters param;
    param = camera.getParameters();

    // modify parameter
    List<Camera.Size> sizes = param.getSupportedPreviewSizes();
    Camera.Size selected = sizes.get(0);
    param.setPreviewSize(selected.width,selected.height);
    camera.setParameters(param);
    try {
        // The Surface has been created, now tell the camera where to draw
        // the preview.
        camera.setDisplayOrientation(90);
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
    } catch (Exception e) {
        // check for exceptions
        System.err.println(e);
        return;
    }
}

@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
    // Now that the size is known, set up the camera parameters and begin
    // the preview.
    refreshCamera();
}

@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
    // stop preview and release camera
    camera.stopPreview();
    camera.release();
    camera = null;
}

public void refreshCamera() {
    if (surfaceHolder.getSurface() == null) {
        // preview surface does not exist
        return;
    }
    // stop preview before making changes
    try {
        camera.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 {
        camera.setPreviewDisplay(surfaceHolder);
        camera.startPreview();
    } catch (Exception e) {

    }
}

}