Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[camera] Take picture with max resolution #3854

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -85,6 +85,7 @@ public class Camera {
private final String cameraName;
private final Size captureSize;
private final Size previewSize;
private final boolean enableTakePictureWithMaxResolution;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the argument for this being a boolean, rather than two independent resolution options? If at some point someone wants a different but non-max option for photos, adding that would make the API extremely messy.

private final boolean enableAudio;
private final Context applicationContext;
private final CamcorderProfile recordingProfile;
Expand Down Expand Up @@ -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;
Expand All @@ -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),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -365,6 +367,7 @@ private void instantiateCamera(MethodCall call, Result result) throws CameraAcce
dartMessenger,
cameraName,
resolutionPreset,
enableTakePictureWithMaxResolution,
enableAudio);

Map<String, Object> reply = new HashMap<>();
Expand Down
8 changes: 7 additions & 1 deletion packages/camera/camera/ios/Classes/CameraPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,7 @@ @interface FLTCam : NSObject <FlutterTexture,
AVCaptureAudioDataOutputSampleBufferDelegate>
@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;
Expand Down Expand Up @@ -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
Expand All @@ -364,6 +366,7 @@ - (instancetype)initWithCameraName:(NSString *)cameraName
} @catch (NSError *e) {
*error = e;
}
_enableTakePictureWithMaxResolution = enableTakePictureWithMaxResolution;
_enableAudio = enableAudio;
_dispatchQueue = dispatchQueue;
_captureSession = [[AVCaptureSession alloc] init];
Expand Down Expand Up @@ -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];
}

Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions packages/camera/camera/lib/src/camera_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ class CameraController extends ValueNotifier<CameraValue> {
CameraController(
this.description,
this.resolutionPreset, {
this.enableTakePictureWithMaxResolution = false,
this.enableAudio = true,
this.imageFormatGroup,
}) : super(const CameraValue.uninitialized());
Expand All @@ -221,6 +222,11 @@ class CameraController extends ValueNotifier<CameraValue> {
/// 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;

Expand Down Expand Up @@ -272,6 +278,7 @@ class CameraController extends ValueNotifier<CameraValue> {
_cameraId = await CameraPlatform.instance.createCamera(
description,
resolutionPreset,
enableTakePictureWithMaxResolution: enableTakePictureWithMaxResolution,
enableAudio: enableAudio,
);

Expand Down