Fixes
diff --git a/app/src/main/java/com/libremobileos/facedetect/FaceBoundsOverlayView.java b/app/src/main/java/com/libremobileos/facedetect/FaceBoundsOverlayView.java
index 88ed9a9..7e3b786 100644
--- a/app/src/main/java/com/libremobileos/facedetect/FaceBoundsOverlayView.java
+++ b/app/src/main/java/com/libremobileos/facedetect/FaceBoundsOverlayView.java
@@ -1,6 +1,5 @@
 package com.libremobileos.facedetect;
 
-import android.annotation.SuppressLint;
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Color;
@@ -8,21 +7,18 @@
 import android.graphics.Paint;
 import android.graphics.RectF;
 import android.util.AttributeSet;
-import android.util.Log;
 import android.view.View;
 
 import androidx.annotation.Nullable;
 
 import com.libremobileos.yifan.face.shared.ImageUtils;
 
-import java.util.Arrays;
-
 public class FaceBoundsOverlayView extends View {
 
 	private RectF[] bounds = null;
 	private Paint paint = null;
 	private Matrix transform = null;
-	private int extra = 0;
+	private int extraw, extrah, viewraww, viewrawh, sensorWidth, sensorHeight;
 
 	public FaceBoundsOverlayView(Context context) {
 		this(context, null);
@@ -43,32 +39,59 @@
 	@Override
 	protected void onDraw(Canvas canvas) {
 		super.onDraw(canvas);
-		if (bounds == null || transform == null) return;
-		if (paint == null) {
-			paint = new Paint();
-			paint.setStyle(Paint.Style.STROKE);
-			paint.setStrokeWidth(10f);
-			paint.setColor(Color.RED);
-		}
+		if (bounds == null || transform == null || paint == null)
+			return; // am I ready yet?
  		for (RectF bound : bounds) {
-			@SuppressLint("DrawAllocation") RectF rect = new RectF(bound);
-			transform.mapRect(rect);
-			rect.offset(0, extra);
-			canvas.drawRect(rect, paint);
+			canvas.drawRect(bound, paint);
 		}
 	}
 
 	@Override
 	protected void onSizeChanged(int w, int h, int oldw, int oldh) {
 		super.onSizeChanged(w, h, oldw, oldh);
-		int newh = (w / 3) * 4;
-		extra = (h - newh) / 2;
-		transform = ImageUtils.getTransformationMatrix(480, 640, w, newh, 0, false);
-		transform.preScale(-1, 1, 480 / 2, 640 / 2); // swap x axis
+		viewraww = w;
+		viewrawh = h;
+		transform = null;
 	}
 
-	public void updateBounds(RectF[] bounds) {
+	// please give me RectF's that wont be used otherwise as I modify them
+	public void updateBounds(RectF[] bounds, int sensorWidth, int sensorHeight) {
 		this.bounds = bounds;
+		// if we have no paint yet, make one
+		if (paint == null) {
+			paint = new Paint();
+			paint.setStyle(Paint.Style.STROKE);
+			paint.setStrokeWidth(10f);
+			paint.setColor(Color.RED);
+		}
+		// if camera size or view size changed, recalculate it
+		if (this.sensorWidth != sensorWidth || this.sensorHeight != sensorHeight || (viewraww + viewrawh) > 0) {
+			this.sensorWidth = sensorWidth;
+			this.sensorHeight = sensorHeight;
+			int oldw = viewraww;
+			int oldh = viewrawh;
+			extraw = 0;
+			extrah = 0;
+			// calculate scaling keeping aspect ratio
+			int newh = (oldw / sensorWidth) * sensorHeight;
+			int neww = (oldh / sensorHeight) * sensorWidth;
+			// calculate out black bars
+			if (neww > oldw) {
+				extrah = (oldh - newh) / 2;
+				viewrawh = newh;
+			} else {
+				extraw = (oldw - neww) / 2;
+				viewraww = neww;
+			}
+			// scale from image size to view size
+			transform = ImageUtils.getTransformationMatrix(sensorWidth, sensorHeight, viewraww, viewrawh, 0, false);
+			viewraww = 0; viewrawh = 0;
+		}
+		// map bounds to view size
+		for (RectF bound : bounds) {
+			transform.mapRect(bound);
+			bound.offset(extraw, extrah);
+		}
 		invalidate();
 	}
 }
diff --git a/app/src/main/java/com/libremobileos/facedetect/MainActivity.java b/app/src/main/java/com/libremobileos/facedetect/MainActivity.java
index 16b44da..f7189d5 100644
--- a/app/src/main/java/com/libremobileos/facedetect/MainActivity.java
+++ b/app/src/main/java/com/libremobileos/facedetect/MainActivity.java
@@ -1,5 +1,7 @@
 package com.libremobileos.facedetect;
 
+import android.content.res.Configuration;
+import android.graphics.Matrix;
 import android.graphics.RectF;
 import android.os.Bundle;
 import android.util.Log;
@@ -10,6 +12,7 @@
 import androidx.annotation.Nullable;
 import androidx.annotation.OptIn;
 import androidx.appcompat.app.AppCompatActivity;
+import androidx.camera.core.Camera;
 import androidx.camera.core.CameraSelector;
 import androidx.camera.core.ExperimentalGetImage;
 import androidx.camera.core.ImageAnalysis;
@@ -33,6 +36,9 @@
 	private PreviewView previewView;
 	private FaceFinder faceFinder;
 	private FaceBoundsOverlayView overlayView;
+	private final Size desiredInputSize = new Size(640, 480);
+	private final int selectedCamera = CameraSelector.LENS_FACING_FRONT;
+	private int previewWidth, previewHeight;
 
 	@Override
 	protected void onCreate(@Nullable Bundle savedInstanceState) {
@@ -42,9 +48,16 @@
 		previewView.setScaleType(PreviewView.ScaleType.FIT_CENTER);
 		overlayView = findViewById(R.id.overlay);
 
-		cameraProviderFuture = ProcessCameraProvider.getInstance(this);
-		faceFinder = FaceFinder.create(this, 480, 640, 0);
+		/* cameras are landscape */
+		if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
+			previewWidth = desiredInputSize.getHeight();
+			previewHeight = desiredInputSize.getWidth();
+		} else {
+			previewWidth = desiredInputSize.getWidth();
+			previewHeight = desiredInputSize.getHeight();
+		}
 
+		cameraProviderFuture = ProcessCameraProvider.getInstance(this);
 		cameraProviderFuture.addListener(() -> {
 			try {
 				ProcessCameraProvider cameraProvider = cameraProviderFuture.get();
@@ -63,29 +76,44 @@
 				.build();
 
 		CameraSelector cameraSelector = new CameraSelector.Builder()
-				.requireLensFacing(CameraSelector.LENS_FACING_FRONT)
+				.requireLensFacing(selectedCamera)
 				.build();
 
 		preview.setSurfaceProvider(previewView.getSurfaceProvider());
 
 		ImageAnalysis imageAnalysis =
 				new ImageAnalysis.Builder()
-						.setTargetResolution(new Size(480, 640))
+						.setTargetResolution(new Size(previewWidth, previewHeight))
 						.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
 						.build();
 
 		imageAnalysis.setAnalyzer(getMainExecutor(), imageProxy -> {
 			Pair<List<Pair<FaceDetector.Face, FaceScanner.Face>>, Long> data = faceFinder.process(BitmapUtils.getBitmap(imageProxy));
 			ArrayList<RectF> bounds = new ArrayList<>();
+			Log.i("cam", String.valueOf(imageProxy.getImageInfo().getRotationDegrees()));
 			for (Pair<FaceDetector.Face, FaceScanner.Face> faceFacePair : data.first) {
-				Log.i("face", "found face id=" + faceFacePair.first.getId() + " conf=" + faceFacePair.first.getConfidence() + " loc=" + faceFacePair.first.getLocation());
-				bounds.add(faceFacePair.first.getLocation());
+				RectF boundingBox = new RectF(faceFacePair.first.getLocation());
+				if (selectedCamera == CameraSelector.LENS_FACING_FRONT) {
+					// camera is frontal so the image is flipped horizontally
+					// flips horizontally
+					Matrix flip = new Matrix();
+					int sensorOrientation = imageProxy.getImageInfo().getRotationDegrees();
+					if (sensorOrientation == 0 || sensorOrientation == 180) {
+						flip.postScale(1, -1, previewWidth / 2.0f, previewHeight / 2.0f);
+					} else {
+						flip.postScale(-1, 1, previewWidth / 2.0f, previewHeight / 2.0f);
+					}
+					flip.mapRect(boundingBox);
+				}
+				bounds.add(boundingBox);
 			}
-			overlayView.updateBounds(bounds.toArray(new RectF[0]));
+			overlayView.updateBounds(bounds.toArray(new RectF[0]), previewWidth, previewHeight);
 			imageProxy.close();
 		});
 
-		cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageAnalysis, preview);
+		Camera camera = cameraProvider.bindToLifecycle((LifecycleOwner)this, cameraSelector, imageAnalysis, preview);
+
+		faceFinder = FaceFinder.create(this, previewWidth, previewHeight, 0);
 	}
 
 }