@capgo/camera-preview 7.4.0-beta.20 → 7.4.0-beta.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -690,30 +690,31 @@ Sets the camera focus to a specific point in the preview.
690
690
 
691
691
  Defines the configuration options for starting the camera preview.
692
692
 
693
- | Prop | Type | Description | Default | Since |
694
- | ---------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----- |
695
- | **`parent`** | <code>string</code> | The parent element to attach the video preview to. | | |
696
- | **`className`** | <code>string</code> | A CSS class name to add to the preview element. | | |
697
- | **`width`** | <code>number</code> | The width of the preview in pixels. Defaults to the screen width. | | |
698
- | **`height`** | <code>number</code> | The height of the preview in pixels. Defaults to the screen height. | | |
699
- | **`x`** | <code>number</code> | The horizontal origin of the preview, in pixels. | | |
700
- | **`y`** | <code>number</code> | The vertical origin of the preview, in pixels. | | |
701
- | **`aspectRatio`** | <code>'4:3' \| '16:9'</code> | The aspect ratio of the camera preview, '4:3' or '16:9' or 'fill'. Cannot be set if width or height is provided, otherwise the call will be rejected. Use setPreviewSize to adjust size after starting. | | 2.0.0 |
702
- | **`gridMode`** | <code><a href="#gridmode">GridMode</a></code> | The grid overlay to display on the camera preview. | <code>"none"</code> | 2.1.0 |
703
- | **`includeSafeAreaInsets`** | <code>boolean</code> | Adjusts the y-position to account for safe areas (e.g., notches). | <code>false</code> | |
704
- | **`toBack`** | <code>boolean</code> | If true, places the preview behind the webview. | <code>true</code> | |
705
- | **`paddingBottom`** | <code>number</code> | Bottom padding for the preview, in pixels. | | |
706
- | **`rotateWhenOrientationChanged`** | <code>boolean</code> | Whether to rotate the preview when the device orientation changes. | <code>true</code> | |
707
- | **`position`** | <code>string</code> | The camera to use. | <code>"rear"</code> | |
708
- | **`storeToFile`** | <code>boolean</code> | If true, saves the captured image to a file and returns the file path. If false, returns a base64 encoded string. | <code>false</code> | |
709
- | **`disableExifHeaderStripping`** | <code>boolean</code> | If true, prevents the plugin from rotating the image based on EXIF data. | <code>false</code> | |
710
- | **`disableAudio`** | <code>boolean</code> | If true, disables the audio stream, preventing audio permission requests. | <code>true</code> | |
711
- | **`lockAndroidOrientation`** | <code>boolean</code> | If true, locks the device orientation while the camera is active. | <code>false</code> | |
712
- | **`enableOpacity`** | <code>boolean</code> | If true, allows the camera preview's opacity to be changed. | <code>false</code> | |
713
- | **`enableZoom`** | <code>boolean</code> | If true, enables pinch-to-zoom functionality on the preview. | <code>false</code> | |
714
- | **`enableVideoMode`** | <code>boolean</code> | If true, uses the video-optimized preset for the camera session. | <code>false</code> | |
715
- | **`deviceId`** | <code>string</code> | The `deviceId` of the camera to use. If provided, `position` is ignored. | | |
716
- | **`initialZoomLevel`** | <code>number</code> | The initial zoom level when starting the camera preview. If the requested zoom level is not available, the native plugin will reject. | <code>1.0</code> | 2.2.0 |
693
+ | Prop | Type | Description | Default | Since |
694
+ | ---------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- | ----- |
695
+ | **`parent`** | <code>string</code> | The parent element to attach the video preview to. | | |
696
+ | **`className`** | <code>string</code> | A CSS class name to add to the preview element. | | |
697
+ | **`width`** | <code>number</code> | The width of the preview in pixels. Defaults to the screen width. | | |
698
+ | **`height`** | <code>number</code> | The height of the preview in pixels. Defaults to the screen height. | | |
699
+ | **`x`** | <code>number</code> | The horizontal origin of the preview, in pixels. | | |
700
+ | **`y`** | <code>number</code> | The vertical origin of the preview, in pixels. | | |
701
+ | **`aspectRatio`** | <code>'4:3' \| '16:9'</code> | The aspect ratio of the camera preview, '4:3' or '16:9' or 'fill'. Cannot be set if width or height is provided, otherwise the call will be rejected. Use setPreviewSize to adjust size after starting. | | 2.0.0 |
702
+ | **`gridMode`** | <code><a href="#gridmode">GridMode</a></code> | The grid overlay to display on the camera preview. | <code>"none"</code> | 2.1.0 |
703
+ | **`includeSafeAreaInsets`** | <code>boolean</code> | Adjusts the y-position to account for safe areas (e.g., notches). | <code>false</code> | |
704
+ | **`toBack`** | <code>boolean</code> | If true, places the preview behind the webview. | <code>true</code> | |
705
+ | **`paddingBottom`** | <code>number</code> | Bottom padding for the preview, in pixels. | | |
706
+ | **`rotateWhenOrientationChanged`** | <code>boolean</code> | Whether to rotate the preview when the device orientation changes. | <code>true</code> | |
707
+ | **`position`** | <code>string</code> | The camera to use. | <code>"rear"</code> | |
708
+ | **`storeToFile`** | <code>boolean</code> | If true, saves the captured image to a file and returns the file path. If false, returns a base64 encoded string. | <code>false</code> | |
709
+ | **`disableExifHeaderStripping`** | <code>boolean</code> | If true, prevents the plugin from rotating the image based on EXIF data. | <code>false</code> | |
710
+ | **`disableAudio`** | <code>boolean</code> | If true, disables the audio stream, preventing audio permission requests. | <code>true</code> | |
711
+ | **`lockAndroidOrientation`** | <code>boolean</code> | If true, locks the device orientation while the camera is active. | <code>false</code> | |
712
+ | **`enableOpacity`** | <code>boolean</code> | If true, allows the camera preview's opacity to be changed. | <code>false</code> | |
713
+ | **`enableZoom`** | <code>boolean</code> | If true, enables pinch-to-zoom functionality on the preview. | <code>false</code> | |
714
+ | **`enableVideoMode`** | <code>boolean</code> | If true, uses the video-optimized preset for the camera session. | <code>false</code> | |
715
+ | **`deviceId`** | <code>string</code> | The `deviceId` of the camera to use. If provided, `position` is ignored. | | |
716
+ | **`initialZoomLevel`** | <code>number</code> | The initial zoom level when starting the camera preview. If the requested zoom level is not available, the native plugin will reject. | <code>1.0</code> | 2.2.0 |
717
+ | **`positioning`** | <code><a href="#camerapositioning">CameraPositioning</a></code> | The vertical positioning of the camera preview. | <code>"center"</code> | 2.3.0 |
717
718
 
718
719
 
719
720
  #### ExifData
@@ -828,6 +829,11 @@ Represents the detailed information of the currently active lens.
828
829
  <code>"rear" | "front"</code>
829
830
 
830
831
 
832
+ #### CameraPositioning
833
+
834
+ <code>"center" | "top" | "bottom"</code>
835
+
836
+
831
837
  #### PictureFormat
832
838
 
833
839
  <code>"jpeg" | "png"</code>
Binary file
@@ -174,7 +174,14 @@ public class CameraPreview
174
174
  Integer height = call.getInt("height");
175
175
  String aspectRatio = call.getString("aspectRatio");
176
176
 
177
- cameraXView.capturePhoto(quality, saveToGallery, width, height, aspectRatio, location);
177
+ cameraXView.capturePhoto(
178
+ quality,
179
+ saveToGallery,
180
+ width,
181
+ height,
182
+ aspectRatio,
183
+ location
184
+ );
178
185
  }
179
186
 
180
187
  @PluginMethod
@@ -493,6 +500,7 @@ public class CameraPreview
493
500
  );
494
501
  final String aspectRatio = call.getString("aspectRatio", "4:3");
495
502
  final String gridMode = call.getString("gridMode", "none");
503
+ final String positioning = call.getString("positioning", "top");
496
504
  final float initialZoomLevel = call.getFloat("initialZoomLevel", 1.0f);
497
505
 
498
506
  // Check for conflict between aspectRatio and size
@@ -576,39 +584,82 @@ public class CameraPreview
576
584
 
577
585
  // Calculate pixel ratio
578
586
  float pixelRatio = metrics.density;
579
-
587
+
580
588
  // The key insight: JavaScript coordinates are relative to the WebView's viewport
581
- // If the WebView is positioned below the status bar (webViewLocationOnScreen[1] > 0),
589
+ // If the WebView is positioned below the status bar (webViewLocationOnScreen[1] > 0),
582
590
  // we need to add that offset when placing native views
583
591
  int webViewTopInset = webViewLocationOnScreen[1];
584
592
  boolean isEdgeToEdgeActive = webViewLocationOnScreen[1] > 0;
585
-
593
+
586
594
  // Log all the positioning information for debugging
587
595
  Log.d("CameraPreview", "WebView Position Debug:");
588
596
  Log.d("CameraPreview", " - webView.getTop(): " + webViewTop);
589
597
  Log.d("CameraPreview", " - webView.getLeft(): " + webViewLeft);
590
- Log.d("CameraPreview", " - webView locationInWindow: (" + webViewLocationInWindow[0] + ", " + webViewLocationInWindow[1] + ")");
591
- Log.d("CameraPreview", " - webView locationOnScreen: (" + webViewLocationOnScreen[0] + ", " + webViewLocationOnScreen[1] + ")");
592
- Log.d("CameraPreview", " - parent locationInWindow: (" + parentLocationInWindow[0] + ", " + parentLocationInWindow[1] + ")");
593
- Log.d("CameraPreview", " - parent locationOnScreen: (" + parentLocationOnScreen[0] + ", " + parentLocationOnScreen[1] + ")");
594
-
598
+ Log.d(
599
+ "CameraPreview",
600
+ " - webView locationInWindow: (" +
601
+ webViewLocationInWindow[0] +
602
+ ", " +
603
+ webViewLocationInWindow[1] +
604
+ ")"
605
+ );
606
+ Log.d(
607
+ "CameraPreview",
608
+ " - webView locationOnScreen: (" +
609
+ webViewLocationOnScreen[0] +
610
+ ", " +
611
+ webViewLocationOnScreen[1] +
612
+ ")"
613
+ );
614
+ Log.d(
615
+ "CameraPreview",
616
+ " - parent locationInWindow: (" +
617
+ parentLocationInWindow[0] +
618
+ ", " +
619
+ parentLocationInWindow[1] +
620
+ ")"
621
+ );
622
+ Log.d(
623
+ "CameraPreview",
624
+ " - parent locationOnScreen: (" +
625
+ parentLocationOnScreen[0] +
626
+ ", " +
627
+ parentLocationOnScreen[1] +
628
+ ")"
629
+ );
630
+
595
631
  // Check if WebView has margins
596
632
  View webView = getBridge().getWebView();
597
633
  ViewGroup.LayoutParams webViewLayoutParams = webView.getLayoutParams();
598
634
  if (webViewLayoutParams instanceof ViewGroup.MarginLayoutParams) {
599
- ViewGroup.MarginLayoutParams marginParams = (ViewGroup.MarginLayoutParams) webViewLayoutParams;
600
- Log.d("CameraPreview", " - webView margins: left=" + marginParams.leftMargin +
601
- ", top=" + marginParams.topMargin +
602
- ", right=" + marginParams.rightMargin +
603
- ", bottom=" + marginParams.bottomMargin);
635
+ ViewGroup.MarginLayoutParams marginParams =
636
+ (ViewGroup.MarginLayoutParams) webViewLayoutParams;
637
+ Log.d(
638
+ "CameraPreview",
639
+ " - webView margins: left=" +
640
+ marginParams.leftMargin +
641
+ ", top=" +
642
+ marginParams.topMargin +
643
+ ", right=" +
644
+ marginParams.rightMargin +
645
+ ", bottom=" +
646
+ marginParams.bottomMargin
647
+ );
604
648
  }
605
-
649
+
606
650
  // Check WebView padding
607
- Log.d("CameraPreview", " - webView padding: left=" + webView.getPaddingLeft() +
608
- ", top=" + webView.getPaddingTop() +
609
- ", right=" + webView.getPaddingRight() +
610
- ", bottom=" + webView.getPaddingBottom());
611
-
651
+ Log.d(
652
+ "CameraPreview",
653
+ " - webView padding: left=" +
654
+ webView.getPaddingLeft() +
655
+ ", top=" +
656
+ webView.getPaddingTop() +
657
+ ", right=" +
658
+ webView.getPaddingRight() +
659
+ ", bottom=" +
660
+ webView.getPaddingBottom()
661
+ );
662
+
612
663
  Log.d("CameraPreview", " - Using webViewTopInset: " + webViewTopInset);
613
664
  Log.d("CameraPreview", " - isEdgeToEdgeActive: " + isEdgeToEdgeActive);
614
665
 
@@ -627,11 +678,39 @@ public class CameraPreview
627
678
 
628
679
  Log.d("CameraPreview", "========================");
629
680
  Log.d("CameraPreview", "POSITIONING CALCULATIONS:");
630
- Log.d("CameraPreview", "1. INPUT - x: " + x + ", y: " + y + ", width: " + width + ", height: " + height);
681
+ Log.d(
682
+ "CameraPreview",
683
+ "1. INPUT - x: " +
684
+ x +
685
+ ", y: " +
686
+ y +
687
+ ", width: " +
688
+ width +
689
+ ", height: " +
690
+ height
691
+ );
631
692
  Log.d("CameraPreview", "2. PIXEL RATIO: " + pixelRatio);
632
- Log.d("CameraPreview", "3. SCREEN - width: " + metrics.widthPixels + ", height: " + metrics.heightPixels);
633
- Log.d("CameraPreview", "4. WEBVIEW - width: " + getBridge().getWebView().getWidth() + ", height: " + getBridge().getWebView().getHeight());
634
- Log.d("CameraPreview", "5. COMPUTED DIMENSIONS - width: " + computedWidth + ", height: " + computedHeight);
693
+ Log.d(
694
+ "CameraPreview",
695
+ "3. SCREEN - width: " +
696
+ metrics.widthPixels +
697
+ ", height: " +
698
+ metrics.heightPixels
699
+ );
700
+ Log.d(
701
+ "CameraPreview",
702
+ "4. WEBVIEW - width: " +
703
+ getBridge().getWebView().getWidth() +
704
+ ", height: " +
705
+ getBridge().getWebView().getHeight()
706
+ );
707
+ Log.d(
708
+ "CameraPreview",
709
+ "5. COMPUTED DIMENSIONS - width: " +
710
+ computedWidth +
711
+ ", height: " +
712
+ computedHeight
713
+ );
635
714
 
636
715
  if (x == -1) {
637
716
  // Center horizontally
@@ -660,34 +739,58 @@ public class CameraPreview
660
739
  }
661
740
 
662
741
  if (y == -1) {
663
- // Center vertically
664
- if (isEdgeToEdgeActive) {
665
- // When WebView is offset from top, center within the available space
666
- // The camera should be centered in the full screen, not just the WebView area
667
- computedY = (metrics.heightPixels - computedHeight) / 2;
668
- Log.d(
669
- "CameraPreview",
670
- "Centering vertically with WebView offset: screenHeight=" +
671
- metrics.heightPixels +
672
- ", webViewTop=" +
673
- webViewTopInset +
674
- ", computedHeight=" +
675
- computedHeight +
676
- ", computedY=" +
677
- computedY
678
- );
679
- } else {
680
- // Normal mode - use full screen height
681
- computedY = (metrics.heightPixels - computedHeight) / 2;
682
- Log.d(
683
- "CameraPreview",
684
- "Centering vertically (normal): screenHeight=" +
685
- metrics.heightPixels +
686
- ", computedHeight=" +
687
- computedHeight +
688
- ", computedY=" +
689
- computedY
690
- );
742
+ // Position vertically based on positioning parameter
743
+ int screenHeight = metrics.heightPixels;
744
+
745
+ switch (positioning) {
746
+ case "top":
747
+ computedY = 0;
748
+ Log.d("CameraPreview", "Positioning at top: computedY=0");
749
+ break;
750
+ case "bottom":
751
+ computedY = screenHeight - computedHeight;
752
+ Log.d(
753
+ "CameraPreview",
754
+ "Positioning at bottom: screenHeight=" +
755
+ screenHeight +
756
+ ", computedHeight=" +
757
+ computedHeight +
758
+ ", computedY=" +
759
+ computedY
760
+ );
761
+ break;
762
+ case "center":
763
+ default:
764
+ // Center vertically
765
+ if (isEdgeToEdgeActive) {
766
+ // When WebView is offset from top, center within the available space
767
+ // The camera should be centered in the full screen, not just the WebView area
768
+ computedY = (screenHeight - computedHeight) / 2;
769
+ Log.d(
770
+ "CameraPreview",
771
+ "Centering vertically with WebView offset: screenHeight=" +
772
+ screenHeight +
773
+ ", webViewTop=" +
774
+ webViewTopInset +
775
+ ", computedHeight=" +
776
+ computedHeight +
777
+ ", computedY=" +
778
+ computedY
779
+ );
780
+ } else {
781
+ // Normal mode - use full screen height
782
+ computedY = (screenHeight - computedHeight) / 2;
783
+ Log.d(
784
+ "CameraPreview",
785
+ "Centering vertically (normal): screenHeight=" +
786
+ screenHeight +
787
+ ", computedHeight=" +
788
+ computedHeight +
789
+ ", computedY=" +
790
+ computedY
791
+ );
792
+ }
793
+ break;
691
794
  }
692
795
  } else {
693
796
  computedY = (int) (y * pixelRatio);
@@ -698,7 +801,7 @@ public class CameraPreview
698
801
  Log.d(
699
802
  "CameraPreview",
700
803
  "Edge-to-edge adjustment: Y position " +
701
- (int)(y * pixelRatio) +
804
+ (int) (y * pixelRatio) +
702
805
  " + inset " +
703
806
  webViewTopInset +
704
807
  " = " +
@@ -719,7 +822,10 @@ public class CameraPreview
719
822
 
720
823
  Log.d(
721
824
  "CameraPreview",
722
- "2b. EDGE-TO-EDGE - " + (isEdgeToEdgeActive ? "ACTIVE (inset=" + webViewTopInset + ")" : "INACTIVE")
825
+ "2b. EDGE-TO-EDGE - " +
826
+ (isEdgeToEdgeActive
827
+ ? "ACTIVE (inset=" + webViewTopInset + ")"
828
+ : "INACTIVE")
723
829
  );
724
830
  Log.d(
725
831
  "CameraPreview",
@@ -1062,7 +1168,7 @@ public class CameraPreview
1062
1168
 
1063
1169
  int x = (xParam != null && xParam > 0) ? (int) (xParam * pixelRatio) : 0;
1064
1170
  int y = (yParam != null && yParam > 0) ? (int) (yParam * pixelRatio) : 0;
1065
-
1171
+
1066
1172
  // Add edge-to-edge inset to Y if active
1067
1173
  if (isEdgeToEdgeActive && y > 0) {
1068
1174
  y += webViewTopInset;
@@ -360,14 +360,21 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
360
360
  Log.d(TAG, "setupPreviewView: Setting grid mode to: " + currentGridMode);
361
361
  gridOverlayView.setGridMode(currentGridMode);
362
362
  });
363
-
363
+
364
364
  // Add a layout listener to update grid bounds when preview view changes size
365
- previewView.addOnLayoutChangeListener((v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
366
- if (left != oldLeft || top != oldTop || right != oldRight || bottom != oldBottom) {
367
- Log.d(TAG, "PreviewView layout changed, updating grid bounds");
368
- updateGridOverlayBounds();
365
+ previewView.addOnLayoutChangeListener(
366
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
367
+ if (
368
+ left != oldLeft ||
369
+ top != oldTop ||
370
+ right != oldRight ||
371
+ bottom != oldBottom
372
+ ) {
373
+ Log.d(TAG, "PreviewView layout changed, updating grid bounds");
374
+ updateGridOverlayBounds();
375
+ }
369
376
  }
370
- });
377
+ );
371
378
 
372
379
  ViewGroup parent = (ViewGroup) webView.getParent();
373
380
  if (parent != null) {
@@ -838,12 +845,24 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
838
845
  String aspectRatio,
839
846
  Location location
840
847
  ) {
841
- Log.d(TAG, "capturePhoto: Starting photo capture with quality: " + quality + ", width: " + width + ", height: " + height + ", aspectRatio: " + aspectRatio);
848
+ Log.d(
849
+ TAG,
850
+ "capturePhoto: Starting photo capture with quality: " +
851
+ quality +
852
+ ", width: " +
853
+ width +
854
+ ", height: " +
855
+ height +
856
+ ", aspectRatio: " +
857
+ aspectRatio
858
+ );
842
859
 
843
860
  // Check for conflicting parameters
844
861
  if (aspectRatio != null && (width != null || height != null)) {
845
862
  if (listener != null) {
846
- listener.onPictureTakenError("Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start.");
863
+ listener.onPictureTakenError(
864
+ "Cannot set both aspectRatio and size (width/height). Use setPreviewSize after start."
865
+ );
847
866
  }
848
867
  return;
849
868
  }
@@ -896,36 +915,56 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
896
915
 
897
916
  // Use the stored aspectRatio if none is provided and no width/height is specified
898
917
  String captureAspectRatio = aspectRatio;
899
- if (width == null && height == null && aspectRatio == null && sessionConfig != null) {
918
+ if (
919
+ width == null &&
920
+ height == null &&
921
+ aspectRatio == null &&
922
+ sessionConfig != null
923
+ ) {
900
924
  captureAspectRatio = sessionConfig.getAspectRatio();
901
925
  // Default to "4:3" if no aspect ratio was set at all
902
926
  if (captureAspectRatio == null) {
903
927
  captureAspectRatio = "4:3";
904
928
  }
905
- Log.d(TAG, "capturePhoto: Using stored aspectRatio: " + captureAspectRatio);
929
+ Log.d(
930
+ TAG,
931
+ "capturePhoto: Using stored aspectRatio: " + captureAspectRatio
932
+ );
906
933
  }
907
-
934
+
908
935
  // Handle aspect ratio if no width/height specified
909
- if (width == null && height == null && captureAspectRatio != null && !captureAspectRatio.isEmpty()) {
936
+ if (
937
+ width == null &&
938
+ height == null &&
939
+ captureAspectRatio != null &&
940
+ !captureAspectRatio.isEmpty()
941
+ ) {
910
942
  // Get the original image dimensions
911
- Bitmap originalBitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
943
+ Bitmap originalBitmap = BitmapFactory.decodeByteArray(
944
+ bytes,
945
+ 0,
946
+ bytes.length
947
+ );
912
948
  int originalWidth = originalBitmap.getWidth();
913
949
  int originalHeight = originalBitmap.getHeight();
914
-
950
+
915
951
  // Parse aspect ratio
916
952
  String[] ratios = captureAspectRatio.split(":");
917
953
  if (ratios.length == 2) {
918
954
  try {
919
955
  float widthRatio = Float.parseFloat(ratios[0]);
920
956
  float heightRatio = Float.parseFloat(ratios[1]);
921
-
957
+
922
958
  // For capture in portrait orientation, swap the aspect ratio (16:9 becomes 9:16)
923
959
  boolean isPortrait = originalHeight > originalWidth;
924
- float targetAspectRatio = isPortrait ? heightRatio / widthRatio : widthRatio / heightRatio;
925
- float originalAspectRatio = (float) originalWidth / originalHeight;
926
-
960
+ float targetAspectRatio = isPortrait
961
+ ? heightRatio / widthRatio
962
+ : widthRatio / heightRatio;
963
+ float originalAspectRatio =
964
+ (float) originalWidth / originalHeight;
965
+
927
966
  int targetWidth, targetHeight;
928
-
967
+
929
968
  if (originalAspectRatio > targetAspectRatio) {
930
969
  // Original is wider than target - fit by height
931
970
  targetHeight = originalHeight;
@@ -935,11 +974,11 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
935
974
  targetWidth = originalWidth;
936
975
  targetHeight = (int) (targetWidth / targetAspectRatio);
937
976
  }
938
-
977
+
939
978
  // Center crop the image
940
979
  int xOffset = (originalWidth - targetWidth) / 2;
941
980
  int yOffset = (originalHeight - targetHeight) / 2;
942
-
981
+
943
982
  Bitmap croppedBitmap = Bitmap.createBitmap(
944
983
  originalBitmap,
945
984
  xOffset,
@@ -947,18 +986,26 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
947
986
  targetWidth,
948
987
  targetHeight
949
988
  );
950
-
989
+
951
990
  ByteArrayOutputStream stream = new ByteArrayOutputStream();
952
- croppedBitmap.compress(Bitmap.CompressFormat.JPEG, quality, stream);
991
+ croppedBitmap.compress(
992
+ Bitmap.CompressFormat.JPEG,
993
+ quality,
994
+ stream
995
+ );
953
996
  bytes = stream.toByteArray();
954
-
997
+
955
998
  // Write EXIF data back to cropped image
956
999
  bytes = writeExifToImageBytes(bytes, exifInterface);
957
-
1000
+
958
1001
  originalBitmap.recycle();
959
1002
  croppedBitmap.recycle();
960
1003
  } catch (NumberFormatException e) {
961
- Log.e(TAG, "Invalid aspect ratio format: " + captureAspectRatio, e);
1004
+ Log.e(
1005
+ TAG,
1006
+ "Invalid aspect ratio format: " + captureAspectRatio,
1007
+ e
1008
+ );
962
1009
  }
963
1010
  }
964
1011
  } else if (width != null && height != null) {
@@ -1616,7 +1663,7 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
1616
1663
 
1617
1664
  int viewWidth = previewView.getWidth();
1618
1665
  int viewHeight = previewView.getHeight();
1619
-
1666
+
1620
1667
  if (viewWidth <= 0 || viewHeight <= 0) {
1621
1668
  throw new Exception(
1622
1669
  "Preview view has invalid dimensions: " + viewWidth + "x" + viewHeight
@@ -2804,7 +2851,7 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
2804
2851
  finalY +
2805
2852
  ")"
2806
2853
  );
2807
-
2854
+
2808
2855
  // Update grid overlay bounds after aspect ratio change
2809
2856
  previewContainer.post(() -> updateGridOverlayBounds());
2810
2857
  }
@@ -2863,14 +2910,8 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
2863
2910
  int webViewTopInset = getWebViewTopInset();
2864
2911
  int webViewLeftInset = getWebViewLeftInset();
2865
2912
 
2866
- int x = Math.max(
2867
- 0,
2868
- (int) ((actualX - webViewLeftInset) / pixelRatio)
2869
- );
2870
- int y = Math.max(
2871
- 0,
2872
- (int) ((actualY - webViewTopInset) / pixelRatio)
2873
- );
2913
+ int x = Math.max(0, (int) ((actualX - webViewLeftInset) / pixelRatio));
2914
+ int y = Math.max(0, (int) ((actualY - webViewTopInset) / pixelRatio));
2874
2915
  int width = (int) (actualWidth / pixelRatio);
2875
2916
  int height = (int) (actualHeight / pixelRatio);
2876
2917
 
@@ -2881,10 +2922,10 @@ public class CameraXView implements LifecycleOwner, LifecycleObserver {
2881
2922
  if (gridOverlayView != null && previewView != null) {
2882
2923
  // Get the actual camera bounds
2883
2924
  Rect cameraBounds = getActualCameraBounds();
2884
-
2925
+
2885
2926
  // Update the grid overlay with the camera bounds
2886
2927
  gridOverlayView.setCameraBounds(cameraBounds);
2887
-
2928
+
2888
2929
  Log.d(
2889
2930
  TAG,
2890
2931
  "updateGridOverlayBounds: Updated grid bounds to " +
@@ -93,7 +93,14 @@ public class GridOverlayView extends View {
93
93
  }
94
94
  }
95
95
 
96
- private void drawGrid(Canvas canvas, int left, int top, int width, int height, int divisions) {
96
+ private void drawGrid(
97
+ Canvas canvas,
98
+ int left,
99
+ int top,
100
+ int width,
101
+ int height,
102
+ int divisions
103
+ ) {
97
104
  float stepX = (float) width / divisions;
98
105
  float stepY = (float) height / divisions;
99
106