Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

⚡️ Improve the performance when taking photos #182

Merged
merged 3 commits into from
Jul 29, 2023
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ To know more about breaking changes, see [Migration Guide][].

### Improvements

- Improve the performance when taking photos.
- Improve the experience when using the exposure slider.
- Prefer `FlashMode.off` for better performance.
- Allow `cameras` to be set repeatedly.
Expand Down
27 changes: 23 additions & 4 deletions lib/src/states/camera_picker_state.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,15 @@ class CameraPickerState extends State<CameraPicker>
/// 可用的相机实例
late List<CameraDescription> cameras;

/// Whether the controller is handling taking picture or recording video.
/// 相机控制器是否在处理拍照或录像
bool isControllerBusy = false;

/// Current exposure offset.
/// 当前曝光值
final ValueNotifier<double> currentExposureOffset = ValueNotifier<double>(0);
final ValueNotifier<double> currentExposureSliderOffset =
ValueNotifier<double>(0);

double maxAvailableExposureOffset = 0;
double minAvailableExposureOffset = 0;
double exposureStep = 0;
Expand Down Expand Up @@ -673,10 +676,17 @@ class CameraPickerState extends State<CameraPicker>
pickerConfig.onError,
);
}
if (controller.value.isTakingPicture) {
if (isControllerBusy) {
return;
}
isControllerBusy = true;
final ExposureMode previousExposureMode = controller.value.exposureMode;
try {
await Future.wait(<Future<void>>[
controller.setFocusMode(FocusMode.locked),
if (previousExposureMode != ExposureMode.locked)
controller.setExposureMode(ExposureMode.locked),
]);
final XFile file = await controller.takePicture();
await controller.pausePreview();
final bool? isCapturedFileHandled = pickerConfig.onXFileCaptured?.call(
Expand All @@ -694,11 +704,17 @@ class CameraPickerState extends State<CameraPicker>
Navigator.of(context).pop(entity);
return;
}
await Future.wait(<Future<void>>[
controller.setFocusMode(FocusMode.auto),
if (previousExposureMode != ExposureMode.locked)
controller.setExposureMode(previousExposureMode),
]);
await controller.resumePreview();
} catch (e) {
realDebugPrint('Error when preview the captured file: $e');
handleErrorWithHandler(e, pickerConfig.onError);
} finally {
isControllerBusy = false;
safeSetState(() {});
}
}
Expand Down Expand Up @@ -741,9 +757,10 @@ class CameraPickerState extends State<CameraPicker>
/// Set record file path and start recording.
/// 设置拍摄文件路径并开始录制视频
Future<void> startRecordingVideo() async {
if (controller.value.isRecordingVideo) {
if (isControllerBusy) {
return;
}
isControllerBusy = true;
try {
await controller.startVideoRecording();
if (isRecordingRestricted) {
Expand All @@ -756,6 +773,7 @@ class CameraPickerState extends State<CameraPicker>
..reset()
..start();
} catch (e, s) {
isControllerBusy = false;
realDebugPrint('Error when start recording video: $e');
if (!controller.value.isRecordingVideo) {
handleErrorWithHandler(e, pickerConfig.onError, s: s);
Expand Down Expand Up @@ -824,6 +842,7 @@ class CameraPickerState extends State<CameraPicker>
handleError();
handleErrorWithHandler(e, pickerConfig.onError, s: s);
} finally {
isControllerBusy = false;
safeSetState(() {});
}
}
Expand Down Expand Up @@ -973,7 +992,7 @@ class CameraPickerState extends State<CameraPicker>
/// The button to switch flash modes.
/// 切换闪光灯模式的按钮
Widget buildFlashModeSwitch(BuildContext context, CameraValue value) {
IconData icon;
final IconData icon;
switch (value.flashMode) {
case FlashMode.off:
icon = Icons.flash_off;
Expand Down
Loading