diff --git a/app/src/main/java/com/simplemobiletools/camera/MainActivity.java b/app/src/main/java/com/simplemobiletools/camera/MainActivity.java index d31882b0..ad5dfc96 100644 --- a/app/src/main/java/com/simplemobiletools/camera/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/camera/MainActivity.java @@ -37,7 +37,13 @@ public class MainActivity extends AppCompatActivity { @OnClick(R.id.toggle_camera) public void toggleCamera() { + if (currCamera == Camera.CameraInfo.CAMERA_FACING_BACK) + currCamera = Camera.CameraInfo.CAMERA_FACING_FRONT; + else + currCamera = Camera.CameraInfo.CAMERA_FACING_BACK; + preview.releaseCamera(); + preview.setCamera(currCamera); } @OnClick(R.id.shutter) @@ -53,8 +59,7 @@ public class MainActivity extends AppCompatActivity { if (cnt == 1) { toggleCameraBtn.setVisibility(View.INVISIBLE); } - Camera camera = Camera.open(currCamera); - preview.setCamera(camera); + preview.setCamera(currCamera); } @Override diff --git a/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java b/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java index 8487f369..f43bbadb 100644 --- a/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java +++ b/app/src/main/java/com/simplemobiletools/camera/PhotoProcessor.java @@ -4,6 +4,7 @@ import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Matrix; +import android.hardware.Camera; import android.media.ExifInterface; import android.media.MediaScannerConnection; import android.os.AsyncTask; @@ -19,10 +20,12 @@ import java.util.Date; public class PhotoProcessor extends AsyncTask { private static final String TAG = PhotoProcessor.class.getSimpleName(); - private static Context context; + private static Context mContext; + private static int mCameraId; - public PhotoProcessor(Context cxt) { - context = cxt; + public PhotoProcessor(Context context, int cameraId) { + mContext = context; + mCameraId = cameraId; } @Override @@ -51,7 +54,7 @@ public class PhotoProcessor extends AsyncTask { } private static File getOutputMediaFile() { - final String appName = context.getResources().getString(R.string.app_name); + final String appName = mContext.getResources().getString(R.string.app_name); final File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appName); if (!mediaStorageDir.exists()) { @@ -67,21 +70,28 @@ public class PhotoProcessor extends AsyncTask { private Bitmap setBitmapRotation(Bitmap bitmap, String path) throws IOException { final ExifInterface exif = new ExifInterface(path); final String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION); + + float angle = 0f; if (orientation.equalsIgnoreCase("6")) { - bitmap = rotateImage(bitmap, 90); + angle = 90; } else if (orientation.equalsIgnoreCase("8")) { - bitmap = rotateImage(bitmap, 270); + angle = 270; } else if (orientation.equalsIgnoreCase("3")) { - bitmap = rotateImage(bitmap, 180); + angle = 180; } else if (orientation.equalsIgnoreCase("0")) { - bitmap = rotateImage(bitmap, 90); + angle = 90; } - return bitmap; + return rotateImage(bitmap, angle); } public static Bitmap rotateImage(Bitmap source, float angle) { final Matrix matrix = new Matrix(); matrix.postRotate(angle); + + final Camera.CameraInfo info = Utils.getCameraInfo(mCameraId); + if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) + matrix.preScale(-1.f, 1.f); + return Bitmap.createBitmap(source, 0, 0, source.getWidth(), source.getHeight(), matrix, true); } @@ -100,6 +110,6 @@ public class PhotoProcessor extends AsyncTask { private void scanPhoto(File photo) { final String[] photoPath = {photo.getAbsolutePath()}; - MediaScannerConnection.scanFile(context, photoPath, null, null); + MediaScannerConnection.scanFile(mContext, photoPath, null, null); } } diff --git a/app/src/main/java/com/simplemobiletools/camera/Preview.java b/app/src/main/java/com/simplemobiletools/camera/Preview.java index d3bced05..8cade030 100644 --- a/app/src/main/java/com/simplemobiletools/camera/Preview.java +++ b/app/src/main/java/com/simplemobiletools/camera/Preview.java @@ -1,11 +1,13 @@ package com.simplemobiletools.camera; +import android.app.Activity; import android.content.Context; import android.graphics.Rect; import android.hardware.Camera; import android.os.Handler; import android.util.Log; import android.view.MotionEvent; +import android.view.Surface; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; @@ -26,23 +28,28 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O private static SurfaceView surfaceView; private static Camera.Size previewSize; private static boolean canTakePicture; + private static Activity activity; + private static int currCameraId; - public Preview(Context cxt) { - super(cxt); + public Preview(Context context) { + super(context); } - public Preview(Context cxt, SurfaceView sv) { - super(cxt); + public Preview(Activity act, SurfaceView sv) { + super(act); + activity = act; surfaceView = sv; surfaceHolder = surfaceView.getHolder(); surfaceHolder.addCallback(this); surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); - canTakePicture = true; + canTakePicture = false; surfaceView.setOnTouchListener(this); } - public void setCamera(Camera newCamera) { + public void setCamera(int cameraId) { + currCameraId = cameraId; + final Camera newCamera = Camera.open(cameraId); if (camera == newCamera) { return; } @@ -55,12 +62,53 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O requestLayout(); final Camera.Parameters params = camera.getParameters(); - params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + final List focusModes = params.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) + params.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + camera.setParameters(params); - camera.setDisplayOrientation(90); + setCameraDisplayOrientation(cameraId, camera); + + if (canTakePicture) { + try { + camera.setPreviewDisplay(surfaceHolder); + } catch (IOException e) { + Log.e(TAG, "setCamera " + e.getMessage()); + } + setupPreview(); + } } } + public static void setCameraDisplayOrientation(int cameraId, android.hardware.Camera camera) { + final Camera.CameraInfo info = Utils.getCameraInfo(cameraId); + 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; + } + camera.setDisplayOrientation(result); + } + public void takePicture() { if (canTakePicture) { camera.takePicture(null, null, takePictureCallback); @@ -74,12 +122,15 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O new Handler().postDelayed(new Runnable() { @Override public void run() { - camera.startPreview(); + if (camera != null) + camera.startPreview(); + canTakePicture = true; } }, PHOTO_PREVIEW_LENGTH); - new PhotoProcessor(getContext()).execute(data); + final Camera.CameraInfo info = Utils.getCameraInfo(currCameraId); + new PhotoProcessor(getContext(), info.facing).execute(data); } }; @@ -101,7 +152,10 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O @Override public void onAutoFocus(boolean success, Camera camera) { camera.cancelAutoFocus(); - parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + final List focusModes = parameters.getSupportedFocusModes(); + if (focusModes.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) + parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); + camera.setParameters(parameters); } }); @@ -134,7 +188,7 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O public void surfaceCreated(SurfaceHolder holder) { try { if (camera != null) { - camera.setPreviewDisplay(holder); + camera.setPreviewDisplay(surfaceHolder); } } catch (IOException e) { Log.e(TAG, "surfaceCreated IOException " + e.getMessage()); @@ -143,6 +197,11 @@ public class Preview extends ViewGroup implements SurfaceHolder.Callback, View.O @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + setupPreview(); + } + + private void setupPreview() { + canTakePicture = true; if (camera != null) { final Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(previewSize.width, previewSize.height); diff --git a/app/src/main/java/com/simplemobiletools/camera/Utils.java b/app/src/main/java/com/simplemobiletools/camera/Utils.java new file mode 100644 index 00000000..ed636f7b --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/camera/Utils.java @@ -0,0 +1,11 @@ +package com.simplemobiletools.camera; + +import android.hardware.Camera; + +public class Utils { + public static Camera.CameraInfo getCameraInfo(int cameraId) { + final Camera.CameraInfo info = new android.hardware.Camera.CameraInfo(); + Camera.getCameraInfo(cameraId, info); + return info; + } +}