Skip to content

Commit e40dab6

Browse files
committed
🚀 Make the camera preview scaled to full screen.
1 parent 5739a67 commit e40dab6

File tree

2 files changed

+74
-15
lines changed

2 files changed

+74
-15
lines changed

example/lib/main.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import 'package:flutter/material.dart';
2+
import 'package:flutter/services.dart';
23
import 'package:wechat_camera_picker/wechat_camera_picker.dart';
34

45
void main() {
56
runApp(MyApp());
7+
SystemChrome.setSystemUIOverlayStyle(
8+
const SystemUiOverlayStyle(statusBarColor: Colors.transparent),
9+
);
610
}
711

812
class MyApp extends StatelessWidget {

lib/src/widget/camera_picker.dart

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,10 @@ class CameraPickerState extends State<CameraPicker>
186186
/// 可用的相机实例
187187
List<CameraDescription> cameras;
188188

189+
/// 当前曝光值
190+
final ValueNotifier<double> _currentExposureOffset =
191+
ValueNotifier<double>(0.0);
192+
189193
/// The maximum available value for exposure.
190194
/// 最大可用曝光值
191195
double _maxAvailableExposureOffset = 0.0;
@@ -194,8 +198,6 @@ class CameraPickerState extends State<CameraPicker>
194198
/// 最小可用曝光值
195199
double _minAvailableExposureOffset = 0.0;
196200

197-
double _currentExposureOffset = 0.0;
198-
199201
/// The maximum available value for zooming.
200202
/// 最大可用缩放值
201203
double _maxAvailableZoom;
@@ -343,6 +345,21 @@ class CameraPickerState extends State<CameraPicker>
343345
}
344346
}
345347

348+
/// Adjust the proper scale type according to the [controller].
349+
/// 通过 [controller] 的预览大小,判断相机预览适用的缩放类型。
350+
_PreviewScaleType get _effectiveScaleType {
351+
assert(controller != null);
352+
final Size _size = controller.value.previewSize;
353+
final Size _scaledSize = _size * (Screens.widthPixels / _size.height);
354+
if (_scaledSize.width > Screens.heightPixels) {
355+
return _PreviewScaleType.width;
356+
} else if (_scaledSize.width < Screens.heightPixels) {
357+
return _PreviewScaleType.height;
358+
} else {
359+
return _PreviewScaleType.none;
360+
}
361+
}
362+
346363
/// Initialize cameras instances.
347364
/// 初始化相机实例
348365
Future<void> initCameras([CameraDescription cameraDescription]) async {
@@ -783,7 +800,9 @@ class CameraPickerState extends State<CameraPicker>
783800
}
784801

785802
Widget _cameraPreview(BuildContext context) {
786-
return Listener(
803+
assert(controller != null);
804+
805+
Widget _preview = Listener(
787806
onPointerDown: (_) => _pointers++,
788807
onPointerUp: (_) => _pointers--,
789808
child: GestureDetector(
@@ -794,6 +813,41 @@ class CameraPickerState extends State<CameraPicker>
794813
child: CameraPreview(controller),
795814
),
796815
);
816+
817+
if (_effectiveScaleType == _PreviewScaleType.none) {
818+
return _preview;
819+
}
820+
821+
double _width;
822+
double _height;
823+
switch (_effectiveScaleType) {
824+
case _PreviewScaleType.width:
825+
_width = Screens.width;
826+
_height = Screens.width / controller.value.aspectRatio;
827+
break;
828+
case _PreviewScaleType.height:
829+
_width = Screens.height * controller.value.aspectRatio;
830+
_height = Screens.height;
831+
break;
832+
default:
833+
_width = Screens.width;
834+
_height = Screens.height;
835+
break;
836+
}
837+
final double _offsetHorizontal = (_width - Screens.width).abs() / -2;
838+
final double _offsetVertical = (_height - Screens.height).abs() / -2;
839+
_preview = Stack(
840+
children: <Widget>[
841+
Positioned(
842+
left: _offsetHorizontal,
843+
right: _offsetHorizontal,
844+
top: _offsetVertical,
845+
bottom: _offsetVertical,
846+
child: _preview,
847+
),
848+
],
849+
);
850+
return _preview;
797851
}
798852

799853
Widget _initializeWrapper({
@@ -817,25 +871,24 @@ class CameraPickerState extends State<CameraPicker>
817871
color: Colors.black,
818872
child: Stack(
819873
fit: StackFit.expand,
874+
alignment: Alignment.center,
820875
children: <Widget>[
821876
if (isInitialized)
822-
Center(
823-
child: RotatedBox(
824-
quarterTurns: widget.cameraQuarterTurns ?? 0,
825-
child: AspectRatio(
826-
aspectRatio: controller.value.aspectRatio,
827-
child: Stack(
828-
children: <Widget>[
829-
Positioned.fill(child: _cameraPreview(context)),
830-
_focusingAreaWidget,
831-
],
832-
),
877+
RotatedBox(
878+
quarterTurns: widget.cameraQuarterTurns ?? 0,
879+
child: AspectRatio(
880+
aspectRatio: controller.value.aspectRatio,
881+
child: Stack(
882+
children: <Widget>[
883+
Positioned.fill(child: _cameraPreview(context)),
884+
_focusingAreaWidget,
885+
],
833886
),
834887
),
835888
),
836889
SafeArea(
837890
child: Padding(
838-
padding: const EdgeInsets.symmetric(vertical: 20.0),
891+
padding: const EdgeInsets.only(bottom: 20.0),
839892
child: Column(
840893
children: <Widget>[
841894
settingsAction,
@@ -852,3 +905,5 @@ class CameraPickerState extends State<CameraPicker>
852905
);
853906
}
854907
}
908+
909+
enum _PreviewScaleType { none, width, height }

0 commit comments

Comments
 (0)