From b25fe889d8fb66776a5d6116648c1da0e87d7c04 Mon Sep 17 00:00:00 2001 From: L Date: Sat, 4 Aug 2018 20:39:04 -0700 Subject: [PATCH 1/2] expose auto exposure and auto focus point of interest functionality (iOS only) --- .../flutter/plugins/camera/CameraPlugin.java | 5 +++++ packages/camera/example/lib/main.dart | 14 +++++++++--- packages/camera/ios/Classes/CameraPlugin.m | 22 +++++++++++++++++++ packages/camera/lib/camera.dart | 20 +++++++++++++++++ 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java index 1d4bedefbbf4..b967e8fe8935 100644 --- a/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java +++ b/packages/camera/android/src/main/java/io/flutter/plugins/camera/CameraPlugin.java @@ -199,6 +199,11 @@ public void onMethodCall(MethodCall call, final Result result) { camera.stopVideoRecording(result); break; } + case "setPointOfInterest": + { + result.notImplemented(); + break; + } case "dispose": { if (camera != null) { diff --git a/packages/camera/example/lib/main.dart b/packages/camera/example/lib/main.dart index 47d8ece9226f..3f5f5ce3e6e4 100644 --- a/packages/camera/example/lib/main.dart +++ b/packages/camera/example/lib/main.dart @@ -95,9 +95,17 @@ class _CameraExampleHomeState extends State { ); } else { return new AspectRatio( - aspectRatio: controller.value.aspectRatio, - child: new CameraPreview(controller), - ); + aspectRatio: controller.value.aspectRatio, + child: GestureDetector( + child: new CameraPreview(controller), + onTapUp: (TapUpDetails details) { + final RenderBox box = context.findRenderObject(); + final Offset localPoint = + box.globalToLocal(details.globalPosition); + final Offset scaledPoint = + localPoint.scale(1 / box.size.width, 1 / box.size.height); + controller.setPointOfInterest(scaledPoint); + })); } } diff --git a/packages/camera/ios/Classes/CameraPlugin.m b/packages/camera/ios/Classes/CameraPlugin.m index 0bfb7515c36c..fc9211e506f0 100644 --- a/packages/camera/ios/Classes/CameraPlugin.m +++ b/packages/camera/ios/Classes/CameraPlugin.m @@ -492,6 +492,28 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result }); [cam start]; } + } else if ([@"setPointOfInterest" isEqualToString:call.method]) { + NSNumber *offsetX = call.arguments[@"offsetX"]; + NSNumber *offsetY = call.arguments[@"offsetY"]; + + NSError *error = nil; + [_camera.captureDevice lockForConfiguration:&error]; + if (error) { + result([error flutterError]); + } else { + if ([_camera.captureDevice isFocusPointOfInterestSupported]) { + _camera.captureDevice.focusPointOfInterest = + CGPointMake(offsetY.floatValue, 1 - offsetX.floatValue); + [_camera.captureDevice setFocusMode:AVCaptureFocusModeContinuousAutoFocus]; + } + if ([_camera.captureDevice isExposurePointOfInterestSupported]) { + _camera.captureDevice.exposurePointOfInterest = + CGPointMake(offsetY.floatValue, 1 - offsetX.floatValue); + [_camera.captureDevice setExposureMode:AVCaptureExposureModeContinuousAutoExposure]; + } + [_camera.captureDevice unlockForConfiguration]; + result(@{}); + } } else { NSDictionary *argsMap = call.arguments; NSUInteger textureId = ((NSNumber *)argsMap[@"textureId"]).unsignedIntegerValue; diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 837e02bf12cc..3981bc73e74f 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -335,6 +335,26 @@ class CameraController extends ValueNotifier { } } + /// Sets the auto focus and auto exposure point. + /// + /// Throws a [CameraException] if the call fails. + Future setPointOfInterest(Offset offset) async { + if (!value.isInitialized || _isDisposed) { + throw new CameraException( + 'Uninitialized CameraController.', + 'takePicture was called on uninitialized CameraController', + ); + } + try { + await _channel.invokeMethod( + 'setPointOfInterest', + {'offsetX': offset.dx, 'offsetY': offset.dy}, + ); + } on PlatformException catch (e) { + throw new CameraException(e.code, e.message); + } + } + /// Releases the resources of this camera. @override Future dispose() async { From 3a0504e688647d9992577a1e1ca82a3211d0236e Mon Sep 17 00:00:00 2001 From: Landon Smith Date: Wed, 12 Sep 2018 21:01:52 -0600 Subject: [PATCH 2/2] remove unnecessary new keywords per updated style guide --- packages/camera/example/lib/main.dart | 2 +- packages/camera/lib/camera.dart | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/camera/example/lib/main.dart b/packages/camera/example/lib/main.dart index 6ba4c316be67..0dec09506020 100644 --- a/packages/camera/example/lib/main.dart +++ b/packages/camera/example/lib/main.dart @@ -94,7 +94,7 @@ class _CameraExampleHomeState extends State { ), ); } else { - return new AspectRatio( + return AspectRatio( aspectRatio: controller.value.aspectRatio, child: GestureDetector( child: CameraPreview(controller), diff --git a/packages/camera/lib/camera.dart b/packages/camera/lib/camera.dart index 900d4585aa01..192271b80b93 100644 --- a/packages/camera/lib/camera.dart +++ b/packages/camera/lib/camera.dart @@ -340,7 +340,7 @@ class CameraController extends ValueNotifier { /// Throws a [CameraException] if the call fails. Future setPointOfInterest(Offset offset) async { if (!value.isInitialized || _isDisposed) { - throw new CameraException( + throw CameraException( 'Uninitialized CameraController.', 'takePicture was called on uninitialized CameraController', ); @@ -351,7 +351,7 @@ class CameraController extends ValueNotifier { {'offsetX': offset.dx, 'offsetY': offset.dy}, ); } on PlatformException catch (e) { - throw new CameraException(e.code, e.message); + throw CameraException(e.code, e.message); } }