From 951a8d5e5edc5dee4d82ccaa709c97b28287a998 Mon Sep 17 00:00:00 2001 From: sergeydesenkoBrickit Date: Sat, 29 Jul 2023 18:29:53 +0300 Subject: [PATCH 1/3] feat(camera_avfoundation): set max resolution from formats that are available for current capture device. --- camera_avfoundation/ios/Classes/FLTCam.m | 29 ++++++++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/camera_avfoundation/ios/Classes/FLTCam.m b/camera_avfoundation/ios/Classes/FLTCam.m index 329fe4b..26365f3 100644 --- a/camera_avfoundation/ios/Classes/FLTCam.m +++ b/camera_avfoundation/ios/Classes/FLTCam.m @@ -162,6 +162,9 @@ - (instancetype)initWithCameraName:(NSString *)cameraName _motionManager = [[CMMotionManager alloc] init]; [_motionManager startAccelerometerUpdates]; + _videoCaptureSession.sessionPreset = AVCaptureSessionPresetInputPriority; + + [self setCaptureSessionPreset:_resolutionPreset]; [self updateOrientation]; @@ -338,12 +341,28 @@ - (NSString *)getTemporaryFilePathWithExtension:(NSString *)extension } - (void)setCaptureSessionPreset:(FLTResolutionPreset)resolutionPreset { + AVCaptureDeviceFormat *bestFormat = nil; + NSUInteger maxHeight = 0; switch (resolutionPreset) { - case FLTResolutionPresetMax: - if ([_videoCaptureSession canSetSessionPreset:AVCaptureSessionPresetPhoto]) { - _videoCaptureSession.sessionPreset = AVCaptureSessionPresetPhoto; - _previewSize = CGSizeMake(4032, 3024); - break; + case FLTResolutionPresetMax: + for ( AVCaptureDeviceFormat *format in [_captureDevice formats] ) { + CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); + NSUInteger height = res.height; + if ( height > maxHeight ) { + maxHeight = height; + bestFormat = format; + } + } + if ( bestFormat ) { + _videoCaptureSession.sessionPreset = AVCaptureSessionPresetInputPriority; + if ( [_captureDevice lockForConfiguration:NULL] == YES ) { + _captureDevice.activeFormat = bestFormat; + [_captureDevice unlockForConfiguration]; + } + _previewSize = + CGSizeMake(_captureDevice.activeFormat.highResolutionStillImageDimensions.width, + _captureDevice.activeFormat.highResolutionStillImageDimensions.height); + break; } if ([_videoCaptureSession canSetSessionPreset:AVCaptureSessionPreset3840x2160]) { _videoCaptureSession.sessionPreset = AVCaptureSessionPreset3840x2160; From 182d1f6ca8103d79a90d0ce16e0f56f3387e2507 Mon Sep 17 00:00:00 2001 From: sergeydesenkoBrickit Date: Sat, 29 Jul 2023 18:38:51 +0300 Subject: [PATCH 2/3] feat(example): add photo resolution logging --- camera/example/lib/main.dart | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/camera/example/lib/main.dart b/camera/example/lib/main.dart index 2fa2ae6..c5721d7 100644 --- a/camera/example/lib/main.dart +++ b/camera/example/lib/main.dart @@ -4,6 +4,7 @@ import 'dart:async'; import 'dart:io'; +import 'dart:ui' as ui; import 'package:camera/camera.dart'; import 'package:flutter/foundation.dart'; @@ -646,7 +647,7 @@ class _CameraExampleHomeState extends State final CameraController cameraController = CameraController( cameraDescription, - kIsWeb ? ResolutionPreset.max : ResolutionPreset.medium, + ResolutionPreset.max, enableAudio: enableAudio, imageFormatGroup: ImageFormatGroup.jpeg, ); @@ -729,11 +730,27 @@ class _CameraExampleHomeState extends State }); if (file != null) { showInSnackBar('Picture saved to ${file.path}'); + + _loadImage(file.path).then((image) { + debugPrint( + 'Picture resolution is ${image.height} x ${image.width}', + ); + }); } } }); } + Future _loadImage(String imagePath) async { + final Uint8List imageBytes = await File(imagePath).readAsBytes(); + final Completer imageCompleter = Completer(); + ui.decodeImageFromList(imageBytes, (ui.Image image) { + imageCompleter.complete(image); + }); + + return imageCompleter.future; + } + void onFlashModeButtonPressed() { if (_flashModeControlRowAnimationController.value == 1) { _flashModeControlRowAnimationController.reverse(); From c5bd911ea922ae38199099d081e53636f334e87a Mon Sep 17 00:00:00 2001 From: sergeydesenkoBrickit Date: Sun, 30 Jul 2023 15:43:35 +0300 Subject: [PATCH 3/3] refactor(camera_avfoundation): code separation --- camera_avfoundation/ios/Classes/FLTCam.m | 49 ++++++++++++++---------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/camera_avfoundation/ios/Classes/FLTCam.m b/camera_avfoundation/ios/Classes/FLTCam.m index 26365f3..82eb84a 100644 --- a/camera_avfoundation/ios/Classes/FLTCam.m +++ b/camera_avfoundation/ios/Classes/FLTCam.m @@ -341,28 +341,21 @@ - (NSString *)getTemporaryFilePathWithExtension:(NSString *)extension } - (void)setCaptureSessionPreset:(FLTResolutionPreset)resolutionPreset { - AVCaptureDeviceFormat *bestFormat = nil; - NSUInteger maxHeight = 0; switch (resolutionPreset) { - case FLTResolutionPresetMax: - for ( AVCaptureDeviceFormat *format in [_captureDevice formats] ) { - CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); - NSUInteger height = res.height; - if ( height > maxHeight ) { - maxHeight = height; - bestFormat = format; - } - } - if ( bestFormat ) { - _videoCaptureSession.sessionPreset = AVCaptureSessionPresetInputPriority; - if ( [_captureDevice lockForConfiguration:NULL] == YES ) { - _captureDevice.activeFormat = bestFormat; - [_captureDevice unlockForConfiguration]; + case FLTResolutionPresetMax: + { + AVCaptureDeviceFormat *bestFormat = [self getHighestResolutionFormatFor:_captureDevice]; + if ( bestFormat ) { + _videoCaptureSession.sessionPreset = AVCaptureSessionPresetInputPriority; + if ( [_captureDevice lockForConfiguration:NULL] == YES ) { + _captureDevice.activeFormat = bestFormat; + [_captureDevice unlockForConfiguration]; + _previewSize = + CGSizeMake(_captureDevice.activeFormat.highResolutionStillImageDimensions.width, + _captureDevice.activeFormat.highResolutionStillImageDimensions.height); + break; + } } - _previewSize = - CGSizeMake(_captureDevice.activeFormat.highResolutionStillImageDimensions.width, - _captureDevice.activeFormat.highResolutionStillImageDimensions.height); - break; } if ([_videoCaptureSession canSetSessionPreset:AVCaptureSessionPreset3840x2160]) { _videoCaptureSession.sessionPreset = AVCaptureSessionPreset3840x2160; @@ -424,6 +417,22 @@ - (void)setCaptureSessionPreset:(FLTResolutionPreset)resolutionPreset { _audioCaptureSession.sessionPreset = _videoCaptureSession.sessionPreset; } +- (AVCaptureDeviceFormat *)getHighestResolutionFormatFor:(AVCaptureDevice*)captureDevice { + AVCaptureDeviceFormat *bestFormat = nil; + NSUInteger maxPixelCount = 0; + for ( AVCaptureDeviceFormat *format in [_captureDevice formats] ) { + CMVideoDimensions res = CMVideoFormatDescriptionGetDimensions(format.formatDescription); + NSUInteger height = res.height; + NSUInteger width = res.width; + NSUInteger pixelCount = height * width; + if ( pixelCount > maxPixelCount ) { + maxPixelCount = pixelCount; + bestFormat = format; + } + } + return bestFormat; +} + - (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {