diff --git a/README.md b/README.md
index 6e4b9c66..2aabf3ca 100644
--- a/README.md
+++ b/README.md
@@ -168,6 +168,7 @@ Documentation for the [uploader](https://github.com/Cap-go/capacitor-uploader)
* [`captureSample(...)`](#capturesample)
* [`getSupportedFlashModes()`](#getsupportedflashmodes)
* [`getHorizontalFov()`](#gethorizontalfov)
+* [`getSupportedPictureSizes()`](#getsupportedpicturesizes)
* [`setFlashMode(...)`](#setflashmode)
* [`flip()`](#flip)
* [`setOpacity(...)`](#setopacity)
@@ -279,6 +280,19 @@ Get horizontal field of view.
--------------------
+### getSupportedPictureSizes()
+
+```typescript
+getSupportedPictureSizes() => Promise<{ supportedPictureSizes: { facing: string; supportedPictureSizes: { width: number; height: number; }[]; }[]; }>
+```
+
+Gets the supported picture sizes for a given device.
+
+**Returns:** Promise<{ supportedPictureSizes: { facing: string; supportedPictureSizes: { width: number; height: number; }[]; }[]; }>
+
+--------------------
+
+
### setFlashMode(...)
```typescript
diff --git a/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java b/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
index 482b9f7d..cadeec95 100644
--- a/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
+++ b/android/src/main/java/com/ahm/capacitor/camera/preview/CameraPreview.java
@@ -5,11 +5,18 @@
import android.app.FragmentManager;
import android.app.FragmentTransaction;
+import android.content.Context;
import android.content.pm.ActivityInfo;
import android.graphics.Color;
+import android.graphics.ImageFormat;
import android.graphics.Point;
import android.hardware.Camera;
+import android.hardware.camera2.CameraAccessException;
+import android.hardware.camera2.CameraCharacteristics;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.params.StreamConfigurationMap;
import android.util.DisplayMetrics;
+import android.util.Size;
import android.util.TypedValue;
import android.view.Display;
import android.view.MotionEvent;
@@ -17,6 +24,7 @@
import android.view.ViewGroup;
import android.widget.FrameLayout;
import androidx.annotation.NonNull;
+import com.getcapacitor.JSArray;
import com.getcapacitor.JSObject;
import com.getcapacitor.Logger;
import com.getcapacitor.PermissionState;
@@ -27,6 +35,7 @@
import com.getcapacitor.annotation.Permission;
import com.getcapacitor.annotation.PermissionCallback;
import java.io.File;
+import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import org.json.JSONArray;
@@ -130,6 +139,70 @@ public void captureSample(PluginCall call) {
fragment.takeSnapshot(quality);
}
+ @PluginMethod
+ public void getSupportedPictureSizes(final PluginCall call) {
+ CameraManager cameraManager = (CameraManager) this.getContext()
+ .getSystemService(Context.CAMERA_SERVICE);
+
+ JSArray ret = new JSArray();
+ try {
+ String[] cameraIdList = cameraManager.getCameraIdList();
+ for (String cameraId : cameraIdList) {
+ CameraCharacteristics characteristics =
+ cameraManager.getCameraCharacteristics(cameraId);
+
+ // Determine the facing of the camera
+ Integer lensFacing = characteristics.get(
+ CameraCharacteristics.LENS_FACING
+ );
+ String facing = "Unknown";
+ if (lensFacing != null) {
+ switch (lensFacing) {
+ case CameraCharacteristics.LENS_FACING_FRONT:
+ facing = "Front";
+ break;
+ case CameraCharacteristics.LENS_FACING_BACK:
+ facing = "Back";
+ break;
+ case CameraCharacteristics.LENS_FACING_EXTERNAL:
+ facing = "External";
+ break;
+ }
+ }
+
+ StreamConfigurationMap map = characteristics.get(
+ CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP
+ );
+ if (map == null) {
+ continue;
+ }
+
+ Size[] jpegSizes = map.getOutputSizes(ImageFormat.JPEG);
+ JSObject camera = new JSObject();
+ camera.put("facing", facing);
+ JSArray supportedPictureSizes = new JSArray();
+ if (jpegSizes != null) {
+ for (Size size : jpegSizes) {
+ JSObject sizeJson = new JSObject();
+ sizeJson.put("width", size.getWidth());
+ sizeJson.put("height", size.getHeight());
+ supportedPictureSizes.put(sizeJson);
+ }
+ camera.put("supportedPictureSizes", supportedPictureSizes);
+ ret.put(camera);
+ }
+ }
+ JSObject finalRet = new JSObject();
+ finalRet.put("supportedPictureSizes", ret);
+ call.resolve(finalRet);
+ } catch (CameraAccessException ex) {
+ Logger.error(getLogTag(), "Cannot call getSupportedPictureSizes", ex);
+ call.reject(
+ String.format("Cannot call getSupportedPictureSizes. Error: %s", ex)
+ );
+ }
+ }
+
@PluginMethod
public void stop(final PluginCall call) {
bridge
diff --git a/ios/Plugin/Plugin.m b/ios/Plugin/Plugin.m
index b8fb86ce..787ae813 100644
--- a/ios/Plugin/Plugin.m
+++ b/ios/Plugin/Plugin.m
@@ -14,4 +14,5 @@
CAP_PLUGIN_METHOD(setFlashMode, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(startRecordVideo, CAPPluginReturnPromise);
CAP_PLUGIN_METHOD(stopRecordVideo, CAPPluginReturnPromise);
+ CAP_PLUGIN_METHOD(getSupportedPictureSizes, CAPPluginReturnPromise);
)
diff --git a/ios/Plugin/Plugin.swift b/ios/Plugin/Plugin.swift
index 295969d7..0a33aa92 100644
--- a/ios/Plugin/Plugin.swift
+++ b/ios/Plugin/Plugin.swift
@@ -81,6 +81,85 @@ public class CameraPreview: CAPPlugin {
cameraController.updateVideoOrientation()
}
+
+ struct CameraInfo {
+ let deviceID: String
+ let position: String
+ let pictureSizes: [CGSize]
+ }
+
+ func getSupportedPictureSizes() -> [CameraInfo] {
+ var cameraInfos = [CameraInfo]()
+
+ // Discover all available cameras
+ let deviceTypes: [AVCaptureDevice.DeviceType] = [
+ .builtInWideAngleCamera,
+ .builtInTelephotoCamera,
+ .builtInUltraWideCamera,
+ .builtInTrueDepthCamera
+ ]
+
+ let session = AVCaptureDevice.DiscoverySession(
+ deviceTypes: deviceTypes,
+ mediaType: .video,
+ position: .unspecified
+ )
+
+ let devices = session.devices
+
+ for device in devices {
+ // Determine the position of the camera
+ var position = "Unknown"
+ switch device.position {
+ case .front:
+ position = "Front"
+ case .back:
+ position = "Back"
+ case .unspecified:
+ position = "Unspecified"
+ @unknown default:
+ position = "Unknown"
+ }
+
+ var pictureSizes = [CGSize]()
+
+ // Get supported formats
+ for format in device.formats {
+ let description = format.formatDescription
+ let dimensions = CMVideoFormatDescriptionGetDimensions(description)
+ let size = CGSize(width: CGFloat(dimensions.width), height: CGFloat(dimensions.height))
+ if !pictureSizes.contains(size) {
+ pictureSizes.append(size)
+ }
+ }
+
+ // Sort sizes in descending order (largest to smallest)
+ pictureSizes.sort { $0.width * $0.height > $1.width * $1.height }
+
+ let cameraInfo = CameraInfo(deviceID: device.uniqueID, position: position, pictureSizes: pictureSizes)
+ cameraInfos.append(cameraInfo)
+ }
+
+ return cameraInfos
+ }
+
+
+ @objc func getSupportedPictureSizes(_ call: CAPPluginCall) {
+ let cameraInfos = getSupportedPictureSizes()
+ call.resolve([
+ "supportedPictureSizes": cameraInfos.map {
+ return [
+ "facing": $0.position,
+ "supportedPictureSizes": $0.pictureSizes.map { size in
+ return [
+ "width": String(describing: size.width),
+ "height": String(describing: size.height),
+ ]
+ }
+ ]
+ }
+ ])
+ }
@objc func start(_ call: CAPPluginCall) {
self.cameraPosition = call.getString("position") ?? "rear"
diff --git a/src/definitions.ts b/src/definitions.ts
index 2bc5cfd2..432e9c99 100644
--- a/src/definitions.ts
+++ b/src/definitions.ts
@@ -120,6 +120,17 @@ export interface CameraPreviewPlugin {
getHorizontalFov(): Promise<{
result: any;
}>;
+ /**
+ * Gets the supported picture sizes for a given device.
+ * @returns {Promise} an Promise that resolves with the supported picture sizes for a given device
+ * @throws An error if the something goes wrong
+ */
+ getSupportedPictureSizes(): Promise<{
+ supportedPictureSizes: {
+ facing: string;
+ supportedPictureSizes: { width: number; height: number }[];
+ }[];
+ }>;
/**
* Set flash mode.
* @param options the options to set the flash mode with