diff --git a/README.md b/README.md index 3224353..c502b77 100644 --- a/README.md +++ b/README.md @@ -151,10 +151,12 @@ This property allows you to specify the target output of the captured image data #### `captureQuality` -Values: `Camera.constants.CaptureQuality.high` or `"high"` (default), `Camera.constants.CaptureQuality.medium` or `"medium"`, `Camera.constants.CaptureQuality.low` or `"low"`, `Camera.constants.CaptureQuality.photo` or `"photo"`. +Values: `Camera.constants.CaptureQuality.high` or `"high"` (default), `Camera.constants.CaptureQuality.medium` or `"medium"`, `Camera.constants.CaptureQuality.low` or `"low"`, `Camera.constants.CaptureQuality.photo` or `"photo"`, `Camera.constants.CaptureQuality["1080p"]` or `"1080p"`, `Camera.constants.CaptureQuality["720p"]` or `"720p"`, `Camera.constants.CaptureQuality["480p"]` or `"480p"`. This property allows you to specify the quality output of the captured image or video. By default the quality is set to high. +When choosing more-specific quality settings (1080p, 720p, 480p), note that each platform and device supports different valid picture/video sizes, and actual resolution within each of these quality settings might differ. There should not be too much variance (if any) for iOS; 1080p should give 1920x1080, 720p should give 1280x720, and 480p should give 640x480 (note that iOS 480p therefore is NOT the typical 16:9 HD aspect ratio, and the typically-HD camera preview screen may differ greatly in aspect from what you actually record!!). For Android, expect more variance: on most Androids, 1080p *should* give 1920x1080 and 720p *should* give 1280x720; however, 480p will at "best" be 853x480 (16:9 HD aspect ratio), but falls back/down to 800x480, 720x480, or "worse", depending on what is closest-but-less-than 853x480 and available on the actual device. If your application requires knowledge of the precise resolution of the output image/video, you might consider manually determine the actual resolution itself after capture has completed (particularly for 480p on Android). + #### `type` Values: `Camera.constants.Type.front` or `"front"`, `Camera.constants.Type.back` or `"back"` (default) diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java index 3280a4e..37b6324 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCamera.java @@ -17,6 +17,9 @@ public class RCTCamera { private final HashMap _cameraInfos; private final HashMap _cameraTypeToIndex; private final Map _cameras; + private static final Resolution RESOLUTION_480P = new Resolution(853, 480); // 480p shoots for a 16:9 HD aspect ratio, but can otherwise fall back/down to any other supported camera sizes, such as 800x480 or 720x480, if (any) present. See getSupportedPictureSizes/getSupportedVideoSizes below. + private static final Resolution RESOLUTION_720P = new Resolution(1280, 720); + private static final Resolution RESOLUTION_1080P = new Resolution(1920, 1080); private boolean _barcodeScannerEnabled = false; private List _barCodeTypes = null; private int _orientation = -1; @@ -191,16 +194,26 @@ public class RCTCamera { Camera.Parameters parameters = camera.getParameters(); Camera.Size pictureSize = null; + List supportedSizes = parameters.getSupportedPictureSizes(); switch (captureQuality) { case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_LOW: - pictureSize = getSmallestSize(parameters.getSupportedPictureSizes()); + pictureSize = getSmallestSize(supportedSizes); break; case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_MEDIUM: - List sizes = parameters.getSupportedPictureSizes(); - pictureSize = sizes.get(sizes.size() / 2); + pictureSize = supportedSizes.get(supportedSizes.size() / 2); break; case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_HIGH: - pictureSize = getBestSize(parameters.getSupportedPictureSizes(), Integer.MAX_VALUE, Integer.MAX_VALUE); + pictureSize = getBestSize(supportedSizes, Integer.MAX_VALUE, Integer.MAX_VALUE); + break; + case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_480P: + pictureSize = getBestSize(supportedSizes, RESOLUTION_480P.width, RESOLUTION_480P.height); + break; + case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_720P: + pictureSize = getBestSize(supportedSizes, RESOLUTION_720P.width, RESOLUTION_720P.height); + break; + case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_1080P: + pictureSize = getBestSize(supportedSizes, RESOLUTION_1080P.width, RESOLUTION_1080P.height); + break; } if (pictureSize != null) { @@ -216,20 +229,33 @@ public class RCTCamera { } Camera.Size videoSize = null; + List supportedSizes = getSupportedVideoSizes(camera); CamcorderProfile cm = null; switch (captureQuality) { case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_LOW: - videoSize = getSmallestSize(getSupportedVideoSizes(camera)); + videoSize = getSmallestSize(supportedSizes); cm = CamcorderProfile.get(_cameraTypeToIndex.get(cameraType), CamcorderProfile.QUALITY_480P); break; case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_MEDIUM: - List sizes = getSupportedVideoSizes(camera); - videoSize = sizes.get(sizes.size() / 2); + videoSize = supportedSizes.get(supportedSizes.size() / 2); cm = CamcorderProfile.get(_cameraTypeToIndex.get(cameraType), CamcorderProfile.QUALITY_720P); break; case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_HIGH: - videoSize = getBestSize(getSupportedVideoSizes(camera), Integer.MAX_VALUE, Integer.MAX_VALUE); + videoSize = getBestSize(supportedSizes, Integer.MAX_VALUE, Integer.MAX_VALUE); cm = CamcorderProfile.get(_cameraTypeToIndex.get(cameraType), CamcorderProfile.QUALITY_HIGH); + break; + case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_480P: + videoSize = getBestSize(supportedSizes, RESOLUTION_480P.width, RESOLUTION_480P.height); + cm = CamcorderProfile.get(_cameraTypeToIndex.get(cameraType), CamcorderProfile.QUALITY_480P); + break; + case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_720P: + videoSize = getBestSize(supportedSizes, RESOLUTION_720P.width, RESOLUTION_720P.height); + cm = CamcorderProfile.get(_cameraTypeToIndex.get(cameraType), CamcorderProfile.QUALITY_720P); + break; + case RCTCameraModule.RCT_CAMERA_CAPTURE_QUALITY_1080P: + videoSize = getBestSize(supportedSizes, RESOLUTION_1080P.width, RESOLUTION_1080P.height); + cm = CamcorderProfile.get(_cameraTypeToIndex.get(cameraType), CamcorderProfile.QUALITY_1080P); + break; } if (cm == null){ @@ -402,4 +428,14 @@ public class RCTCamera { this.info = info; } } + + private static class Resolution { + public int width; + public int height; + + public Resolution(final int width, final int height) { + this.width = width; + this.height = height; + } + } } diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java index deb11af..d3ee2cc 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraModule.java @@ -76,6 +76,9 @@ public class RCTCameraModule extends ReactContextBaseJavaModule public static final String RCT_CAMERA_CAPTURE_QUALITY_HIGH = "high"; public static final String RCT_CAMERA_CAPTURE_QUALITY_MEDIUM = "medium"; public static final String RCT_CAMERA_CAPTURE_QUALITY_LOW = "low"; + public static final String RCT_CAMERA_CAPTURE_QUALITY_1080P = "1080p"; + public static final String RCT_CAMERA_CAPTURE_QUALITY_720P = "720p"; + public static final String RCT_CAMERA_CAPTURE_QUALITY_480P = "480p"; public static final int MEDIA_TYPE_IMAGE = 1; public static final int MEDIA_TYPE_VIDEO = 2; @@ -193,6 +196,9 @@ public class RCTCameraModule extends ReactContextBaseJavaModule put("medium", RCT_CAMERA_CAPTURE_QUALITY_MEDIUM); put("high", RCT_CAMERA_CAPTURE_QUALITY_HIGH); put("photo", RCT_CAMERA_CAPTURE_QUALITY_HIGH); + put("480p", RCT_CAMERA_CAPTURE_QUALITY_480P); + put("720p", RCT_CAMERA_CAPTURE_QUALITY_720P); + put("1080p", RCT_CAMERA_CAPTURE_QUALITY_1080P); } }); } diff --git a/ios/RCTCameraManager.h b/ios/RCTCameraManager.h index 80702c4..38f0d66 100644 --- a/ios/RCTCameraManager.h +++ b/ios/RCTCameraManager.h @@ -13,7 +13,10 @@ typedef NS_ENUM(NSInteger, RCTCameraCaptureSessionPreset) { RCTCameraCaptureSessionPresetLow = 0, RCTCameraCaptureSessionPresetMedium = 1, RCTCameraCaptureSessionPresetHigh = 2, - RCTCameraCaptureSessionPresetPhoto = 3 + RCTCameraCaptureSessionPresetPhoto = 3, + RCTCameraCaptureSessionPreset480p = 4, + RCTCameraCaptureSessionPreset720p = 5, + RCTCameraCaptureSessionPreset1080p = 6 }; typedef NS_ENUM(NSInteger, RCTCameraCaptureMode) { diff --git a/ios/RCTCameraManager.m b/ios/RCTCameraManager.m index 3403ab1..910d6fb 100644 --- a/ios/RCTCameraManager.m +++ b/ios/RCTCameraManager.m @@ -34,7 +34,7 @@ RCT_EXPORT_MODULE(); self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.session]; self.previewLayer.needsDisplayOnBoundsChange = YES; #endif - + if(!self.camera){ self.camera = [[RCTCamera alloc] initWithManager:self bridge:self.bridge]; } @@ -86,7 +86,13 @@ RCT_EXPORT_MODULE(); @"high": @(RCTCameraCaptureSessionPresetHigh), @"AVCaptureSessionPresetHigh": @(RCTCameraCaptureSessionPresetHigh), @"photo": @(RCTCameraCaptureSessionPresetPhoto), - @"AVCaptureSessionPresetPhoto": @(RCTCameraCaptureSessionPresetPhoto) + @"AVCaptureSessionPresetPhoto": @(RCTCameraCaptureSessionPresetPhoto), + @"480p": @(RCTCameraCaptureSessionPreset480p), + @"AVCaptureSessionPreset640x480": @(RCTCameraCaptureSessionPreset480p), + @"720p": @(RCTCameraCaptureSessionPreset720p), + @"AVCaptureSessionPreset1280x720": @(RCTCameraCaptureSessionPreset720p), + @"1080p": @(RCTCameraCaptureSessionPreset1080p), + @"AVCaptureSessionPreset1920x1080": @(RCTCameraCaptureSessionPreset1080p) }, @"CaptureTarget": @{ @"memory": @(RCTCameraCaptureTargetMemory), @@ -136,6 +142,15 @@ RCT_CUSTOM_VIEW_PROPERTY(captureQuality, NSInteger, RCTCamera) { case RCTCameraCaptureSessionPresetPhoto: qualityString = AVCaptureSessionPresetPhoto; break; + case RCTCameraCaptureSessionPreset1080p: + qualityString = AVCaptureSessionPreset1920x1080; + break; + case RCTCameraCaptureSessionPreset720p: + qualityString = AVCaptureSessionPreset1280x720; + break; + case RCTCameraCaptureSessionPreset480p: + qualityString = AVCaptureSessionPreset640x480; + break; } [self setCaptureQuality:qualityString];