Skip to content

Commit 2b6dcfb

Browse files
authored
⚡️ Improve the performance when taking photos (#182)
1 parent 90df06d commit 2b6dcfb

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ To know more about breaking changes, see [Migration Guide][].
1616

1717
### Improvements
1818

19+
- Improve the performance when taking photos.
1920
- Improve the experience when using the exposure slider.
2021
- Prefer `FlashMode.off` for better performance.
2122
- Allow `cameras` to be set repeatedly.

lib/src/states/camera_picker_state.dart

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,15 @@ class CameraPickerState extends State<CameraPicker>
5656
/// 可用的相机实例
5757
late List<CameraDescription> cameras;
5858

59+
/// Whether the controller is handling taking picture or recording video.
60+
/// 相机控制器是否在处理拍照或录像
61+
bool isControllerBusy = false;
62+
5963
/// Current exposure offset.
6064
/// 当前曝光值
6165
final ValueNotifier<double> currentExposureOffset = ValueNotifier<double>(0);
6266
final ValueNotifier<double> currentExposureSliderOffset =
6367
ValueNotifier<double>(0);
64-
6568
double maxAvailableExposureOffset = 0;
6669
double minAvailableExposureOffset = 0;
6770
double exposureStep = 0;
@@ -673,10 +676,17 @@ class CameraPickerState extends State<CameraPicker>
673676
pickerConfig.onError,
674677
);
675678
}
676-
if (controller.value.isTakingPicture) {
679+
if (isControllerBusy) {
677680
return;
678681
}
682+
isControllerBusy = true;
683+
final ExposureMode previousExposureMode = controller.value.exposureMode;
679684
try {
685+
await Future.wait(<Future<void>>[
686+
controller.setFocusMode(FocusMode.locked),
687+
if (previousExposureMode != ExposureMode.locked)
688+
controller.setExposureMode(ExposureMode.locked),
689+
]);
680690
final XFile file = await controller.takePicture();
681691
await controller.pausePreview();
682692
final bool? isCapturedFileHandled = pickerConfig.onXFileCaptured?.call(
@@ -694,11 +704,17 @@ class CameraPickerState extends State<CameraPicker>
694704
Navigator.of(context).pop(entity);
695705
return;
696706
}
707+
await Future.wait(<Future<void>>[
708+
controller.setFocusMode(FocusMode.auto),
709+
if (previousExposureMode != ExposureMode.locked)
710+
controller.setExposureMode(previousExposureMode),
711+
]);
697712
await controller.resumePreview();
698713
} catch (e) {
699714
realDebugPrint('Error when preview the captured file: $e');
700715
handleErrorWithHandler(e, pickerConfig.onError);
701716
} finally {
717+
isControllerBusy = false;
702718
safeSetState(() {});
703719
}
704720
}
@@ -741,9 +757,10 @@ class CameraPickerState extends State<CameraPicker>
741757
/// Set record file path and start recording.
742758
/// 设置拍摄文件路径并开始录制视频
743759
Future<void> startRecordingVideo() async {
744-
if (controller.value.isRecordingVideo) {
760+
if (isControllerBusy) {
745761
return;
746762
}
763+
isControllerBusy = true;
747764
try {
748765
await controller.startVideoRecording();
749766
if (isRecordingRestricted) {
@@ -756,6 +773,7 @@ class CameraPickerState extends State<CameraPicker>
756773
..reset()
757774
..start();
758775
} catch (e, s) {
776+
isControllerBusy = false;
759777
realDebugPrint('Error when start recording video: $e');
760778
if (!controller.value.isRecordingVideo) {
761779
handleErrorWithHandler(e, pickerConfig.onError, s: s);
@@ -824,6 +842,7 @@ class CameraPickerState extends State<CameraPicker>
824842
handleError();
825843
handleErrorWithHandler(e, pickerConfig.onError, s: s);
826844
} finally {
845+
isControllerBusy = false;
827846
safeSetState(() {});
828847
}
829848
}
@@ -973,7 +992,7 @@ class CameraPickerState extends State<CameraPicker>
973992
/// The button to switch flash modes.
974993
/// 切换闪光灯模式的按钮
975994
Widget buildFlashModeSwitch(BuildContext context, CameraValue value) {
976-
IconData icon;
995+
final IconData icon;
977996
switch (value.flashMode) {
978997
case FlashMode.off:
979998
icon = Icons.flash_off;

0 commit comments

Comments
 (0)