diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java index 4c1370f2f3cb..af3baecd6609 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/Camera.java @@ -4,7 +4,7 @@ package io.flutter.plugins.camera; -import static io.flutter.plugins.camera.CameraUtils.computeBestPreviewSize; +import static io.flutter.plugins.camera.CameraUtils.computeBestCaptureSize; import android.annotation.SuppressLint; import android.annotation.TargetApi; @@ -85,6 +85,7 @@ public class Camera { private final String cameraName; private final Size captureSize; private final Size previewSize; + private final boolean enableTakePictureWithMaxResolution; private final boolean enableAudio; private final Context applicationContext; private final CamcorderProfile recordingProfile; @@ -125,12 +126,14 @@ public Camera( final DartMessenger dartMessenger, final String cameraName, final String resolutionPreset, + final boolean enableTakePictureWithMaxResolution, final boolean enableAudio) throws CameraAccessException { if (activity == null) { throw new IllegalStateException("No activity available!"); } this.cameraName = cameraName; + this.enableTakePictureWithMaxResolution = enableTakePictureWithMaxResolution; this.enableAudio = enableAudio; this.flutterTexture = flutterTexture; this.dartMessenger = dartMessenger; @@ -150,8 +153,18 @@ public Camera( ResolutionPreset preset = ResolutionPreset.valueOf(resolutionPreset); recordingProfile = CameraUtils.getBestAvailableCamcorderProfileForResolutionPreset(cameraName, preset); - captureSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight); - previewSize = computeBestPreviewSize(cameraName, preset); + previewSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight); + if (enableTakePictureWithMaxResolution) { + captureSize = + computeBestCaptureSize( + cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)); + Log.i("Camera", "enableTakePictureWithMaxResolution"); + } else { + captureSize = new Size(recordingProfile.videoFrameWidth, recordingProfile.videoFrameHeight); + } + Log.i("Camera", "[Preview Resolution] :" + previewSize); + Log.i("Camera", "[Capture Resolution] :" + captureSize); + cameraZoom = new CameraZoom( cameraCharacteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE), diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java index b4d4689f2b4e..dabb49310ab0 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/CameraUtils.java @@ -82,16 +82,6 @@ static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String ori } } - static Size computeBestPreviewSize(String cameraName, ResolutionPreset preset) { - if (preset.ordinal() > ResolutionPreset.high.ordinal()) { - preset = ResolutionPreset.high; - } - - CamcorderProfile profile = - getBestAvailableCamcorderProfileForResolutionPreset(cameraName, preset); - return new Size(profile.videoFrameWidth, profile.videoFrameHeight); - } - static Size computeBestCaptureSize(StreamConfigurationMap streamConfigurationMap) { // For still image captures, we use the largest available size. return Collections.max( diff --git a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java index 50bca6349217..8a0cc43babf3 100644 --- a/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java +++ b/packages/camera/camera/android/src/main/java/io/flutter/plugins/camera/MethodCallHandlerImpl.java @@ -352,6 +352,8 @@ void stopListening() { private void instantiateCamera(MethodCall call, Result result) throws CameraAccessException { String cameraName = call.argument("cameraName"); String resolutionPreset = call.argument("resolutionPreset"); + boolean enableTakePictureWithMaxResolution = + call.argument("enableTakePictureWithMaxResolution"); boolean enableAudio = call.argument("enableAudio"); TextureRegistry.SurfaceTextureEntry flutterSurfaceTexture = textureRegistry.createSurfaceTexture(); @@ -365,6 +367,7 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce dartMessenger, cameraName, resolutionPreset, + enableTakePictureWithMaxResolution, enableAudio); Map reply = new HashMap<>(); diff --git a/packages/camera/camera/ios/Classes/CameraPlugin.m b/packages/camera/camera/ios/Classes/CameraPlugin.m index 5c43f78a8c4b..75a82a0b2e4e 100644 --- a/packages/camera/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/camera/ios/Classes/CameraPlugin.m @@ -306,6 +306,7 @@ @interface FLTCam : NSObject @property(readonly, nonatomic) int64_t textureId; @property(nonatomic, copy) void (^onFrameAvailable)(void); +@property BOOL enableTakePictureWithMaxResolution; @property BOOL enableAudio; @property(nonatomic) FLTImageStreamHandler *imageStreamHandler; @property(nonatomic) FlutterMethodChannel *methodChannel; @@ -353,6 +354,7 @@ @implementation FLTCam { - (instancetype)initWithCameraName:(NSString *)cameraName resolutionPreset:(NSString *)resolutionPreset +enableTakePictureWithMaxResolution:(BOOL)enableTakePictureWithMaxResolution enableAudio:(BOOL)enableAudio orientation:(UIDeviceOrientation)orientation dispatchQueue:(dispatch_queue_t)dispatchQueue @@ -364,6 +366,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName } @catch (NSError *e) { *error = e; } + _enableTakePictureWithMaxResolution = enableTakePictureWithMaxResolution; _enableAudio = enableAudio; _dispatchQueue = dispatchQueue; _captureSession = [[AVCaptureSession alloc] init]; @@ -459,7 +462,8 @@ - (void)updateOrientation:(UIDeviceOrientation)orientation - (void)captureToFile:(FlutterResult)result API_AVAILABLE(ios(10)) { AVCapturePhotoSettings *settings = [AVCapturePhotoSettings photoSettings]; - if (_resolutionPreset == max) { + if (_resolutionPreset == max || _enableTakePictureWithMaxResolution == true) { + NSLog(@"setHighResolutionPhotoEnabled"); [settings setHighResolutionPhotoEnabled:YES]; } @@ -1332,10 +1336,12 @@ - (void)handleMethodCallAsync:(FlutterMethodCall *)call result:(FlutterResult)re } else if ([@"create" isEqualToString:call.method]) { NSString *cameraName = call.arguments[@"cameraName"]; NSString *resolutionPreset = call.arguments[@"resolutionPreset"]; + NSNumber *enableTakePictureWithMaxResolution = call.arguments[@"enableTakePictureWithMaxResolution"]; NSNumber *enableAudio = call.arguments[@"enableAudio"]; NSError *error; FLTCam *cam = [[FLTCam alloc] initWithCameraName:cameraName resolutionPreset:resolutionPreset + enableTakePictureWithMaxResolution:[enableTakePictureWithMaxResolution boolValue] enableAudio:[enableAudio boolValue] orientation:[[UIDevice currentDevice] orientation] dispatchQueue:_dispatchQueue diff --git a/packages/camera/camera/lib/src/camera_controller.dart b/packages/camera/camera/lib/src/camera_controller.dart index 3284a9b01fa2..4652080c1e3e 100644 --- a/packages/camera/camera/lib/src/camera_controller.dart +++ b/packages/camera/camera/lib/src/camera_controller.dart @@ -206,6 +206,7 @@ class CameraController extends ValueNotifier { CameraController( this.description, this.resolutionPreset, { + this.enableTakePictureWithMaxResolution = false, this.enableAudio = true, this.imageFormatGroup, }) : super(const CameraValue.uninitialized()); @@ -221,6 +222,11 @@ class CameraController extends ValueNotifier { /// See also: [ResolutionPreset]. final ResolutionPreset resolutionPreset; + /// Whether to use max resolution for takePicture method, + /// It may be higher than ResolutionPreset.max, because the max resolution is for still image. + /// When the value is false, resolution set in resolutionPreset will be used for takePicture. + final bool enableTakePictureWithMaxResolution; + /// Whether to include audio when recording a video. final bool enableAudio; @@ -272,6 +278,7 @@ class CameraController extends ValueNotifier { _cameraId = await CameraPlatform.instance.createCamera( description, resolutionPreset, + enableTakePictureWithMaxResolution: enableTakePictureWithMaxResolution, enableAudio: enableAudio, );