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

Commit

Permalink
[camera_platform_interface] Add platform interface methods for settin…
Browse files Browse the repository at this point in the history
…g auto exposure. (#3345)

* Added platform interface methods for setting auto exposure.

* Added platform interface methods for setting auto exposure.

* Remove workspace files
  • Loading branch information
BeMacized committed Dec 28, 2020
1 parent 3ec0d64 commit 1c00905
Show file tree
Hide file tree
Showing 11 changed files with 494 additions and 27 deletions.
4 changes: 4 additions & 0 deletions packages/camera/camera_platform_interface/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 1.2.0

- Added interface to support automatic exposure.

## 1.1.0

- Added an optional `maxVideoDuration` parameter to the `startVideoRecording` method, which allows implementations to limit the duration of a video recording.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import '../../camera_platform_interface.dart';

/// Generic Event coming from the native side of Camera.
///
/// All [CameraEvent]s contain the `cameraId` that originated the event. This
Expand Down Expand Up @@ -45,6 +47,12 @@ class CameraInitializedEvent extends CameraEvent {
/// The height of the preview in pixels.
final double previewHeight;

/// The default exposure mode
final ExposureMode exposureMode;

/// Whether setting exposure points is supported.
final bool exposurePointSupported;

/// Build a CameraInitialized event triggered from the camera represented by
/// `cameraId`.
///
Expand All @@ -54,13 +62,17 @@ class CameraInitializedEvent extends CameraEvent {
int cameraId,
this.previewWidth,
this.previewHeight,
this.exposureMode,
this.exposurePointSupported,
) : super(cameraId);

/// Converts the supplied [Map] to an instance of the [CameraInitializedEvent]
/// class.
CameraInitializedEvent.fromJson(Map<String, dynamic> json)
: previewWidth = json['previewWidth'],
previewHeight = json['previewHeight'],
exposureMode = deserializeExposureMode(json['exposureMode']),
exposurePointSupported = json['exposurePointSupported'],
super(json['cameraId']);

/// Converts the [CameraInitializedEvent] instance into a [Map] instance that
Expand All @@ -69,6 +81,8 @@ class CameraInitializedEvent extends CameraEvent {
'cameraId': cameraId,
'previewWidth': previewWidth,
'previewHeight': previewHeight,
'exposureMode': serializeExposureMode(exposureMode),
'exposurePointSupported': exposurePointSupported,
};

@override
Expand All @@ -78,11 +92,17 @@ class CameraInitializedEvent extends CameraEvent {
other is CameraInitializedEvent &&
runtimeType == other.runtimeType &&
previewWidth == other.previewWidth &&
previewHeight == other.previewHeight;
previewHeight == other.previewHeight &&
exposureMode == other.exposureMode &&
exposurePointSupported == other.exposurePointSupported;

@override
int get hashCode =>
super.hashCode ^ previewWidth.hashCode ^ previewHeight.hashCode;
super.hashCode ^
previewWidth.hashCode ^
previewHeight.hashCode ^
exposureMode.hashCode ^
exposurePointSupported.hashCode;
}

/// An event fired when the resolution preset of the camera has changed.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:math';

import 'package:camera_platform_interface/camera_platform_interface.dart';
import 'package:camera_platform_interface/src/utils/utils.dart';
Expand Down Expand Up @@ -189,6 +190,62 @@ class MethodChannelCamera extends CameraPlatform {
},
);

@override
Future<void> setExposureMode(int cameraId, ExposureMode mode) =>
_channel.invokeMethod<void>(
'setExposureMode',
<String, dynamic>{
'cameraId': cameraId,
'mode': serializeExposureMode(mode),
},
);

@override
Future<void> setExposurePoint(int cameraId, Point<double> point) {
assert(point == null || point.x >= 0 && point.x <= 1);
assert(point == null || point.y >= 0 && point.y <= 1);
return _channel.invokeMethod<void>(
'setExposurePoint',
<String, dynamic>{
'cameraId': cameraId,
'reset': point == null,
'x': point?.x,
'y': point?.y,
},
);
}

@override
Future<double> getMinExposureOffset(int cameraId) =>
_channel.invokeMethod<double>(
'getMinExposureOffset',
<String, dynamic>{'cameraId': cameraId},
);

@override
Future<double> getMaxExposureOffset(int cameraId) =>
_channel.invokeMethod<double>(
'getMaxExposureOffset',
<String, dynamic>{'cameraId': cameraId},
);

@override
Future<double> getExposureOffsetStepSize(int cameraId) =>
_channel.invokeMethod<double>(
'getExposureOffsetStepSize',
<String, dynamic>{'cameraId': cameraId},
);

@override
Future<double> setExposureOffset(int cameraId, double offset) =>
_channel.invokeMethod<double>(
'setExposureOffset',
<String, dynamic>{
'cameraId': cameraId,
'offset': offset,
},
);

@override
Future<double> getMaxZoomLevel(int cameraId) => _channel.invokeMethod<double>(
'getMaxZoomLevel',
Expand Down Expand Up @@ -269,6 +326,8 @@ class MethodChannelCamera extends CameraPlatform {
cameraId,
call.arguments['previewWidth'],
call.arguments['previewHeight'],
deserializeExposureMode(call.arguments['exposureMode']),
call.arguments['exposurePointSupported'],
));
break;
case 'resolution_changed':
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
// found in the LICENSE file.

import 'dart:async';
import 'dart:math';

import 'package:camera_platform_interface/camera_platform_interface.dart';
import 'package:camera_platform_interface/src/method_channel/method_channel_camera.dart';
import 'package:camera_platform_interface/src/types/exposure_mode.dart';
import 'package:cross_file/cross_file.dart';
import 'package:flutter/widgets.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
Expand Down Expand Up @@ -116,6 +118,48 @@ abstract class CameraPlatform extends PlatformInterface {
throw UnimplementedError('setFlashMode() is not implemented.');
}

/// Sets the exposure mode for taking pictures.
Future<void> setExposureMode(int cameraId, ExposureMode mode) {
throw UnimplementedError('setExposureMode() is not implemented.');
}

/// Sets the exposure point for automatically determining the exposure value.
Future<void> setExposurePoint(int cameraId, Point<double> point) {
throw UnimplementedError('setExposurePoint() is not implemented.');
}

/// Gets the minimum supported exposure offset for the selected camera in EV units.
Future<double> getMinExposureOffset(int cameraId) {
throw UnimplementedError('getMinExposureOffset() is not implemented.');
}

/// Gets the maximum supported exposure offset for the selected camera in EV units.
Future<double> getMaxExposureOffset(int cameraId) {
throw UnimplementedError('getMaxExposureOffset() is not implemented.');
}

/// Gets the supported step size for exposure offset for the selected camera in EV units.
///
/// Returns 0 when the camera supports using a free value without stepping.
Future<double> getExposureOffsetStepSize(int cameraId) {
throw UnimplementedError('getMinExposureOffset() is not implemented.');
}

/// Sets the exposure offset for the selected camera.
///
/// The supplied [offset] value should be in EV units. 1 EV unit represents a
/// doubling in brightness. It should be between the minimum and maximum offsets
/// obtained through `getMinExposureOffset` and `getMaxExposureOffset` respectively.
/// Throws a `CameraException` when an illegal offset is supplied.
///
/// When the supplied [offset] value does not align with the step size obtained
/// through `getExposureStepSize`, it will automatically be rounded to the nearest step.
///
/// Returns the (rounded) offset value that was set.
Future<double> setExposureOffset(int cameraId, double offset) {
throw UnimplementedError('setExposureOffset() is not implemented.');
}

/// Gets the maximum supported zoom level for the selected camera.
Future<double> getMaxZoomLevel(int cameraId) {
throw UnimplementedError('getMaxZoomLevel() is not implemented.');
Expand All @@ -129,7 +173,7 @@ abstract class CameraPlatform extends PlatformInterface {
/// Set the zoom level for the selected camera.
///
/// The supplied [zoom] value should be between 1.0 and the maximum supported
/// zoom level returned by the `getMaxZoomLevel`. Throws an `CameraException`
/// zoom level returned by the `getMaxZoomLevel`. Throws a `CameraException`
/// when an illegal zoom level is supplied.
Future<void> setZoomLevel(int cameraId, double zoom) {
throw UnimplementedError('setZoomLevel() is not implemented.');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/// The possible exposure modes that can be set for a camera.
enum ExposureMode {
/// Automatically determine exposure settings.
auto,

/// Lock the currently determined exposure settings.
locked,
}

/// Returns the exposure mode as a String.
String serializeExposureMode(ExposureMode exposureMode) {
switch (exposureMode) {
case ExposureMode.locked:
return 'locked';
case ExposureMode.auto:
return 'auto';
default:
throw ArgumentError('Unknown ExposureMode value');
}
}

/// Returns the exposure mode for a given String.
ExposureMode deserializeExposureMode(String str) {
switch (str) {
case "locked":
return ExposureMode.locked;
case "auto":
return ExposureMode.auto;
default:
throw ArgumentError('"$str" is not a valid ExposureMode value');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ export 'camera_description.dart';
export 'resolution_preset.dart';
export 'camera_exception.dart';
export 'flash_mode.dart';
export 'exposure_mode.dart';
2 changes: 1 addition & 1 deletion packages/camera/camera_platform_interface/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: A common platform interface for the camera plugin.
homepage: https://github.com/flutter/plugins/tree/master/packages/camera/camera_platform_interface
# NOTE: We strongly prefer non-breaking changes, even at the expense of a
# less-clean API. See https://flutter.dev/go/platform-interface-breaking-changes
version: 1.1.0
version: 1.2.0

dependencies:
flutter:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,84 @@ void main() {
);
});

test(
'Default implementation of setExposureMode() should throw unimplemented error',
() {
// Arrange
final cameraPlatform = ExtendsCameraPlatform();

// Act & Assert
expect(
() => cameraPlatform.setExposureMode(1, null),
throwsUnimplementedError,
);
});

test(
'Default implementation of setExposurePoint() should throw unimplemented error',
() {
// Arrange
final cameraPlatform = ExtendsCameraPlatform();

// Act & Assert
expect(
() => cameraPlatform.setExposurePoint(1, null),
throwsUnimplementedError,
);
});

test(
'Default implementation of getMinExposureOffset() should throw unimplemented error',
() {
// Arrange
final cameraPlatform = ExtendsCameraPlatform();

// Act & Assert
expect(
() => cameraPlatform.getMinExposureOffset(1),
throwsUnimplementedError,
);
});

test(
'Default implementation of getMaxExposureOffset() should throw unimplemented error',
() {
// Arrange
final cameraPlatform = ExtendsCameraPlatform();

// Act & Assert
expect(
() => cameraPlatform.getMaxExposureOffset(1),
throwsUnimplementedError,
);
});

test(
'Default implementation of getExposureOffsetStepSize() should throw unimplemented error',
() {
// Arrange
final cameraPlatform = ExtendsCameraPlatform();

// Act & Assert
expect(
() => cameraPlatform.getExposureOffsetStepSize(1),
throwsUnimplementedError,
);
});

test(
'Default implementation of setExposureOffset() should throw unimplemented error',
() {
// Arrange
final cameraPlatform = ExtendsCameraPlatform();

// Act & Assert
expect(
() => cameraPlatform.setExposureOffset(1, null),
throwsUnimplementedError,
);
});

test(
'Default implementation of startVideoRecording() should throw unimplemented error',
() {
Expand Down

0 comments on commit 1c00905

Please sign in to comment.