Skip to content

Instantly share code, notes, and snippets.

@ashwin-sp
Created February 18, 2018 18:59
Show Gist options
  • Save ashwin-sp/94df0205a15d744218dfa28362ca248f to your computer and use it in GitHub Desktop.
Save ashwin-sp/94df0205a15d744218dfa28362ca248f to your computer and use it in GitHub Desktop.
public class CameraHandler {
private static final String TAG = CameraHandler.class.getSimpleName();
public static final int IMAGE_WIDTH = 640;
public static final int IMAGE_HEIGHT = 480;
private static final int MAX_IMAGES = 1;
private CameraDevice mCameraDevice;
private CameraCaptureSession mCaptureSession;
/**
* An {@link ImageReader} that handles still image capture.
*/
private ImageReader mImageReader;
// Lazy-loaded singleton, so only one instance of the camera is created.
private CameraHandler() {
}
private static class InstanceHolder {
private static CameraHandler mCamera = new CameraHandler();
}
public static CameraHandler getInstance() {
return InstanceHolder.mCamera;
}
/**
* Initialize the camera device
*/
public void initializeCamera(Context context,
Handler backgroundHandler,
ImageReader.OnImageAvailableListener imageAvailableListener) {
// Discover the camera instance
CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
String[] camIds = {};
try {
camIds = manager.getCameraIdList();
} catch (CameraAccessException e) {
Log.d(TAG, "Cam access exception getting IDs", e);
}
if (camIds.length < 1) {
Log.d(TAG, "No cameras found");
return;
}
String id = camIds[0];
Log.d(TAG, "Using camera id " + id);
// Initialize the image processor
mImageReader = ImageReader.newInstance(IMAGE_WIDTH, IMAGE_HEIGHT,
ImageFormat.JPEG, MAX_IMAGES);
mImageReader.setOnImageAvailableListener(
imageAvailableListener, backgroundHandler);
// Open the camera resource
try {
manager.openCamera(id, mStateCallback, backgroundHandler);
} catch (CameraAccessException cae) {
Log.d(TAG, "Camera access exception", cae);
}
}
/**
* Callback handling device state changes
*/
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Opened camera.");
mCameraDevice = cameraDevice;
}
@Override
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Camera disconnected, closing.");
closeCaptureSession();
cameraDevice.close();
}
@Override
public void onError(@NonNull CameraDevice cameraDevice, int i) {
Log.d(TAG, "Camera device error, closing.");
closeCaptureSession();
cameraDevice.close();
}
@Override
public void onClosed(@NonNull CameraDevice cameraDevice) {
Log.d(TAG, "Closed camera, releasing");
mCameraDevice = null;
}
};
/**
* Begin a still image capture
*/
public void takePicture() {
if (mCameraDevice == null) {
Log.w(TAG, "Cannot capture image. Camera not initialized.");
return;
}
// Here, we create a CameraCaptureSession for capturing still images.
try {
mCameraDevice.createCaptureSession(
Collections.singletonList(mImageReader.getSurface()),
mSessionCallback,
null);
} catch (CameraAccessException cae) {
Log.d(TAG, "access exception while preparing pic", cae);
}
}
/**
* Callback handling session state changes
*/
private CameraCaptureSession.StateCallback mSessionCallback =
new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
// The camera is already closed
if (mCameraDevice == null) {
return;
}
// When the session is ready, we start capture.
mCaptureSession = cameraCaptureSession;
triggerImageCapture();
}
@Override
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
Log.w(TAG, "Failed to configure camera");
}
};
/**
* Execute a new capture request within the active session
*/
private void triggerImageCapture() {
try {
final CaptureRequest.Builder captureBuilder =
mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
captureBuilder.addTarget(mImageReader.getSurface());
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON);
Log.d(TAG, "Capture request created.");
mCaptureSession.capture(captureBuilder.build(), mCaptureCallback, null);
} catch (CameraAccessException cae) {
Log.d(TAG, "camera capture exception");
}
}
/**
* Callback handling capture session events
*/
private final CameraCaptureSession.CaptureCallback mCaptureCallback =
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureProgressed(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull CaptureResult partialResult) {
Log.d(TAG, "Partial result");
}
@Override
public void onCaptureCompleted(@NonNull CameraCaptureSession session,
@NonNull CaptureRequest request,
@NonNull TotalCaptureResult result) {
session.close();
mCaptureSession = null;
Log.d(TAG, "CaptureSession closed");
}
};
private void closeCaptureSession() {
if (mCaptureSession != null) {
try {
mCaptureSession.close();
} catch (Exception ex) {
Log.e(TAG, "Could not close capture session", ex);
}
mCaptureSession = null;
}
}
/**
* Close the camera resources
*/
public void shutDown() {
closeCaptureSession();
if (mCameraDevice != null) {
mCameraDevice.close();
}
}
/**
* Helpful debugging method: Dump all supported camera formats to log. You don't need to run
* this for normal operation, but it's very helpful when porting this code to different
* hardware.
*/
public static void dumpFormatInfo(Context context) {
CameraManager manager = (CameraManager) context.getSystemService(CAMERA_SERVICE);
String[] camIds = {};
try {
camIds = manager.getCameraIdList();
} catch (CameraAccessException e) {
Log.d(TAG, "Cam access exception getting IDs");
}
if (camIds.length < 1) {
Log.d(TAG, "No cameras found");
}
String id = camIds[0];
Log.d(TAG, "Using camera id " + id);
try {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(id);
StreamConfigurationMap configs = characteristics.get(
CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
for (int format : configs.getOutputFormats()) {
Log.d(TAG, "Getting sizes for format: " + format);
for (Size s : configs.getOutputSizes(format)) {
Log.d(TAG, "\t" + s.toString());
}
}
int[] effects = characteristics.get(CameraCharacteristics.CONTROL_AVAILABLE_EFFECTS);
for (int effect : effects) {
Log.d(TAG, "Effect available: " + effect);
}
} catch (CameraAccessException e) {
Log.d(TAG, "Cam access exception getting characteristics.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment