Well, here I am going to write a tutorial for you on capture using Camera , including some common camera features.
Step 1: Create a Preview Class
public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = "CameraPreview";
private SurfaceHolder mHolder;
private Camera mCamera;
public CameraPreview(Context context, Camera camera) {
super(context);
mCamera = camera;
mHolder = getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
startPreview();
}
public void resetCamera(Camera camera) {
mCamera = camera;
}
public void startPreview() {
try {
mCamera.setPreviewDisplay(mHolder);
mCamera.startPreview();
} catch (Exception e) {
Log.d(TAG, "Error starting camera preview: " + e.getMessage());
}
}
}
2. FrameLayout, .
<FrameLayout
android:id="@+id/cameraPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
3: camera . .
private void initCameraPreview(final int cameraId, final boolean createPreview) {
mCamera = getCameraInstance(cameraId);
setupCameraParameters(cameraId);
if (createPreview) {
mPreview = new CameraPreview(this, mCamera);
mPreviewHolder.addView(mPreview);
}
mReadyToCapture = true;
}
private Camera getCameraInstance(int cameraId) {
Camera c = null;
try {
c = Camera.open(cameraId);
} catch (Exception e) {
e.printStackTrace();
}
return c;
}
private void setupCameraParameters(int cameraId) {
boolean hasFlash;
Camera.Parameters parameters = mCamera.getParameters();
mPreviewSize = determineBestPreviewSize(parameters);
parameters.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
Camera.Size bestPictureSize = determineBestPictureSize(parameters);
parameters.setPictureSize(bestPictureSize.width, bestPictureSize.height);
hasFlash = Util.hasSystemFeature(this, PackageManager.FEATURE_CAMERA_FLASH);
if (mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT) {
hasFlash = Util.hasFrontCameraFlash(parameters);
} else {
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
}
if (hasFlash)
parameters.setFlashMode(mFlashMode);
int[] orientations = Util.getCameraDisplayOrientation(this, cameraId);
mDisplayOrientation = orientations[0];
mLayoutOrientation = orientations[1];
mCamera.setDisplayOrientation(mDisplayOrientation);
mCamera.setParameters(parameters);
}
private Camera.Size determineBestPreviewSize(Camera.Parameters parameters) {
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
return determineBestSize(sizes);
}
private Camera.Size determineBestPictureSize(Camera.Parameters parameters) {
List<Camera.Size> sizes = parameters.getSupportedPictureSizes();
return determineBestSize(sizes);
}
private Camera.Size determineBestSize(List<Camera.Size> sizes) {
Camera.Size bestSize = null;
for (Camera.Size currentSize : sizes) {
boolean isDesiredRatio = (currentSize.width / 4) == (currentSize.height / 3);
boolean isBetterSize = (bestSize == null || currentSize.width > bestSize.width);
boolean isInBounds = currentSize.width <= PICTURE_SIZE_MAX_WIDTH;
if (isDesiredRatio && isInBounds && isBetterSize) {
bestSize = currentSize;
}
}
if (bestSize == null) {
return sizes.get(0);
}
return bestSize;
}
4:
private void swapCamera() {
if (!(Camera.getNumberOfCameras() > 1)) {
return;
}
mReadyToCapture = false;
mCamera.stopPreview();
releaseCamera(false);
if (mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK)
mCurrentCameraId = Camera.CameraInfo.CAMERA_FACING_FRONT;
else
mCurrentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
initCameraPreview(mCurrentCameraId, false);
mPreview.resetCamera(mCamera);
mPreview.startPreview();
}
5:
private void toggleFlash() {
if (Util.hasSystemFeature(this, PackageManager.FEATURE_CAMERA_FLASH)) {
Camera.Parameters parameters = mCamera.getParameters();
if (mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_FRONT) {
if (!Util.hasFrontCameraFlash(parameters)) {
return;
}
}
mReadyToCapture = false;
if (Camera.Parameters.FLASH_MODE_ON.equals(parameters.getFlashMode())) {
mFlashMode = Camera.Parameters.FLASH_MODE_OFF;
} else {
mFlashMode = Camera.Parameters.FLASH_MODE_ON;
}
mCameraHandler.post(new Runnable() {
@Override
public void run() {
mCamera.stopPreview();
releaseCamera(false);
initCameraPreview(mCurrentCameraId, false);
mPreview.resetCamera(mCamera);
mPreview.startPreview();
}
});
} else {
}
}
6:
private void releaseCamera(boolean remove) {
if (mCamera != null) {
if (remove)
mPreview.getHolder().removeCallback(mPreview);
mCamera.release();
mCamera = null;
}
}
7: .
public static boolean hasSystemFeature(Context context, String feature) {
return context.getPackageManager().hasSystemFeature(feature);
}
public static boolean hasFrontCameraFlash(Camera.Parameters cameraParameters) {
boolean result = true;
if (cameraParameters.getFlashMode() == null) {
result = false;
}
List<String> supportedFlashModes = cameraParameters.getSupportedFlashModes();
if (supportedFlashModes == null || supportedFlashModes.isEmpty()
|| supportedFlashModes.size() == 1 &&
supportedFlashModes.get(0).equals(Camera.Parameters.FLASH_MODE_OFF)) {
result = false;
}
return result;
}
public static int[] getCameraDisplayOrientation(Activity activity,
int cameraId) {
Camera.CameraInfo info =
new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0:
degrees = 0;
break;
case Surface.ROTATION_90:
degrees = 90;
break;
case Surface.ROTATION_180:
degrees = 180;
break;
case Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360;
} else {
result = (info.orientation - degrees + 360) % 360;
}
return new int[]{result, degrees};
}
8:
if (null != mCamera && mReadyToCapture) {
mCameraOrientationListener.rememberOrientation();
mCamera.takePicture(mShutter, null, mPicture)
}
private Camera.ShutterCallback mShutter = new Camera.ShutterCallback() {
@Override
public void onShutter() {
}
};
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
mReadyToCapture = false;
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
int rotation = ((mCurrentCameraId == Camera.CameraInfo.CAMERA_FACING_BACK ? mDisplayOrientation :
((360 - mDisplayOrientation) % 360)) + mCameraOrientationListener.getRememberedOrientation()
+ mLayoutOrientation) % 360;
if (rotation != 0) {
Matrix matrix = new Matrix();
matrix.postRotate(rotation);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
}
}
};
9:
public class CameraOrientationListener extends OrientationEventListener {
private int currentNormalizedOrientation;
private int rememberedNormalizedOrientation;
public CameraOrientationListener(Context context) {
super(context, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public void onOrientationChanged(int orientation) {
if (orientation != ORIENTATION_UNKNOWN) {
currentNormalizedOrientation = normalize(orientation);
}
}
private int normalize(int degrees) {
if (degrees > 315 || degrees <= 45) {
return 0;
}
if (degrees > 45 && degrees <= 135) {
return 90;
}
if (degrees > 135 && degrees <= 225) {
return 180;
}
if (degrees > 225 && degrees <= 315) {
return 270;
}
throw new RuntimeException("The physics as we know them are no more. Watch out for anomalies.");
}
public void rememberOrientation() {
rememberedNormalizedOrientation = currentNormalizedOrientation;
}
public int getRememberedOrientation() {
return rememberedNormalizedOrientation;
}
}
10:
@Override
public void onPause() {
super.onPause();
mReadyToCapture = false;
releaseCamera(true);
}
@Override
public void onResume() {
super.onResume();
removePreview();
mReadyToCapture = false;
smoothCameraLoading();
}
private void removePreview() {
mPreviewHolder.removeAllViews();
}
private void smoothCameraLoading() {
mCameraHandler.post(new Runnable() {
@Override
public void run() {
initCameraPreview(mCurrentCameraId, true);
}
});
}
11:
private String mFlashMode = Camera.Parameters.FLASH_MODE_OFF;
private int mCurrentCameraId = Camera.CameraInfo.CAMERA_FACING_BACK;
private int mDisplayOrientation;
private int mLayoutOrientation;
private boolean mReadyToCapture = false;
private Camera.Size mPreviewSize;
private FrameLayout mPreviewHolder;
private Camera mCamera;
private CameraPreview mPreview;
private Handler mCameraHandler;
private CameraOrientationListener mCameraOrientationListener;
private FrameLayout mRootView;