Skip to content

Commit 190a2ea

Browse files
authored
⚡️ Improve the scaling calculate for the camera preview (#62)
1 parent 7ec3b34 commit 190a2ea

File tree

1 file changed

+37
-69
lines changed

1 file changed

+37
-69
lines changed

lib/src/widgets/camera_picker.dart

Lines changed: 37 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -471,19 +471,25 @@ class CameraPickerState extends State<CameraPicker>
471471
}
472472
}
473473

474-
/// Adjust the proper scale type according to the [controller].
475-
/// 通过 [controller] 的预览大小,判断相机预览适用的缩放类型。
476-
_PreviewScaleType _effectiveScaleType(BoxConstraints constraints) {
477-
final Size _size = controller.value.previewSize!;
478-
final Size _scaledSize =
479-
_size * constraints.maxWidth * Screens.scale / _size.height;
480-
if (_scaledSize.width > constraints.maxHeight * Screens.scale) {
481-
return _PreviewScaleType.width;
482-
} else if (_scaledSize.width < constraints.maxHeight * Screens.scale) {
483-
return _PreviewScaleType.height;
484-
} else {
485-
return _PreviewScaleType.none;
474+
/// Adjust the proper scale type according to the [constraints].
475+
/// 根据 [constraints] 获取相机预览适用的缩放。
476+
double _effectiveCameraScale(
477+
BoxConstraints constraints,
478+
CameraController controller,
479+
) {
480+
// Fetch the biggest size from the constraints.
481+
Size size = constraints.biggest;
482+
// Flip the size when the preview needs to turn with an odd count of quarters.
483+
if (widget.cameraQuarterTurns % 2 != 0) {
484+
size = size.flipped;
485+
}
486+
// Calculate scale depending on the size and camera ratios.
487+
double scale = size.aspectRatio * controller.value.aspectRatio;
488+
// Prevent scaling down.
489+
if (scale < 1) {
490+
scale = 1 / scale;
486491
}
492+
return scale;
487493
}
488494

489495
/// Initialize cameras instances.
@@ -1333,33 +1339,6 @@ class CameraPickerState extends State<CameraPicker>
13331339
),
13341340
);
13351341

1336-
final _PreviewScaleType scale = _effectiveScaleType(constraints);
1337-
if (scale == _PreviewScaleType.none) {
1338-
return _preview;
1339-
}
1340-
1341-
double _width;
1342-
double _height;
1343-
switch (scale) {
1344-
case _PreviewScaleType.width:
1345-
_width = constraints.maxWidth;
1346-
if (constraints.maxWidth <= constraints.maxHeight) {
1347-
_height = constraints.maxWidth * controller.value.aspectRatio;
1348-
} else {
1349-
_height = constraints.maxWidth / controller.value.aspectRatio;
1350-
}
1351-
break;
1352-
case _PreviewScaleType.height:
1353-
_width = constraints.maxHeight / controller.value.aspectRatio;
1354-
_height = constraints.maxHeight;
1355-
break;
1356-
default:
1357-
_width = constraints.maxWidth;
1358-
_height = constraints.maxHeight;
1359-
break;
1360-
}
1361-
final double _offsetHorizontal = (_width - constraints.maxWidth).abs() / -2;
1362-
final double _offsetVertical = (_height - constraints.maxHeight).abs() / -2;
13631342
// Flip the preview if the user is using a front camera to match the result.
13641343
if (currentCamera.lensDirection == CameraLensDirection.front) {
13651344
_preview = Transform(
@@ -1368,19 +1347,13 @@ class CameraPickerState extends State<CameraPicker>
13681347
child: _preview,
13691348
);
13701349
}
1371-
_preview = Stack(
1372-
children: <Widget>[
1373-
Positioned(
1374-
left: _offsetHorizontal,
1375-
right: _offsetHorizontal,
1376-
top: _offsetVertical,
1377-
bottom: _offsetVertical,
1378-
child: RotatedBox(
1379-
quarterTurns: -widget.cameraQuarterTurns,
1380-
child: _preview,
1381-
),
1382-
),
1383-
],
1350+
1351+
_preview = RotatedBox(
1352+
quarterTurns: -widget.cameraQuarterTurns,
1353+
child: Transform.scale(
1354+
scale: _effectiveCameraScale(constraints, controller),
1355+
child: Center(child: _preview),
1356+
),
13841357
);
13851358
return _preview;
13861359
}
@@ -1409,22 +1382,19 @@ class CameraPickerState extends State<CameraPicker>
14091382
required CameraValue value,
14101383
required BoxConstraints constraints,
14111384
}) {
1412-
return AspectRatio(
1413-
aspectRatio: value.aspectRatio,
1414-
child: RepaintBoundary(
1415-
child: Stack(
1416-
children: <Widget>[
1417-
Positioned.fill(
1418-
child: _cameraPreview(
1419-
context,
1420-
orientation: value.deviceOrientation,
1421-
constraints: constraints,
1422-
),
1385+
return RepaintBoundary(
1386+
child: Stack(
1387+
children: <Widget>[
1388+
Positioned.fill(
1389+
child: _cameraPreview(
1390+
context,
1391+
orientation: value.deviceOrientation,
1392+
constraints: constraints,
14231393
),
1424-
if (widget.foregroundBuilder != null)
1425-
Positioned.fill(child: widget.foregroundBuilder!(value)),
1426-
],
1427-
),
1394+
),
1395+
if (widget.foregroundBuilder != null)
1396+
Positioned.fill(child: widget.foregroundBuilder!(value)),
1397+
],
14281398
),
14291399
);
14301400
}
@@ -1487,5 +1457,3 @@ class CameraPickerState extends State<CameraPicker>
14871457
);
14881458
}
14891459
}
1490-
1491-
enum _PreviewScaleType { none, width, height }

0 commit comments

Comments
 (0)