我使用CameraPreview来测量物体的高度,但问题是我无法全屏设置cameraPreview高度..
我尝试过定位小部件,它填满了屏幕,但图像被拉伸了。 我尝试过Transform Widget,但是高度没有填满全屏,空白即将到来。图像没有拉伸。
我的代码:
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(
children: <Widget>[
Transform.scale(
scale: controller.value.aspectRatio/deviceRatio,
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),);
请帮助我调整 CameraPreview“全屏”而不进行图像拉伸..
CameraValue.aspectRatio 返回宽度/高度而不是高度/宽度,并且 CameraPreview 现在处理 AspectRatio 本身,因此我认为工作代码片段如下:
/// only work inside WidgetsApp or MaterialApp, which introduces a MediaQuery
final scale = 1 / (controller.value.aspectRatio * MediaQuery.of(context).size.aspectRatio);
return Transform.scale(
scale: scale,
alignment: Alignment.topCenter,
child: CameraPreview(controller),
);
更新:
通过变换缩放后,在
TransitionRoute中使用时,预览可能会超出屏幕尺寸限制。 (当托管在 CupertinoPageRoute 中时,拖动手势将清楚地显示这一点)。 所以我认为剪辑预览以使其完全匹配屏幕尺寸是个好主意。
final mediaSize = MediaQuery.of(context).size;
final scale = 1 / (controller.value.aspectRatio * mediaSize.aspectRatio);
return ClipRect(
clipper: _MediaSizeClipper(mediaSize),
child: Transform.scale(
scale: scale,
alignment: Alignment.topCenter,
child: CameraPreview(controller),
),
);
class _MediaSizeClipper extends CustomClipper<Rect> {
final Size mediaSize;
const _MediaSizeClipper(this.mediaSize);
@override
Rect getClip(Size size) {
return Rect.fromLTWH(0, 0, mediaSize.width, mediaSize.height);
}
@override
bool shouldReclip(CustomClipper<Rect> oldClipper) {
return true;
}
}
CameraPreview
将
FittedBox
包裹在 BoxFit.cover
中,并确保父容器等于您要填充的空间。@override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
return Scaffold(
body: cameraController == null
? const Text("Loading Camera...")
: Container(
width: size.width,
height: size.height,
child: FittedBox(
fit: BoxFit.cover,
child: Container(
width: 100, // the actual width is not important here
child: CameraPreview(cameraController!)),
)));
}
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Stack(
children: <Widget>[
Center(
child:Transform.scale(
scale: controller.value.aspectRatio/deviceRatio,
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),),);
LayoutBuilder(
builder: (context, constraints) {
return SizedBox(
width: constraints.maxWidth,
height: constraints.maxHeight,
child: CameraPreview(controller),
);
},
),
它会像魅力一样发挥作用
var isPortrait =
MediaQuery.of(context).orientation == Orientation.portrait;
Size mediaSize = MediaQuery.of(context).size;
return SizedBox(
width: mediaSize.width,
height: mediaSize.height,
child: FittedBox(
fit: BoxFit.cover,
child: SizedBox(
width: isPortrait
? _controller!.value.previewSize!.height
: _controller!.value.previewSize!.width,
height: isPortrait
? _controller!.value.previewSize!.width
: _controller!.value.previewSize!.height,
child: CameraPreview(_controller!)),
),
);
我有两个状态小部件字段:
cameraControllerKey
,用于引用保存 CameraPreview 的容器。
cameraPreviewScale
用于存储原始cameraPreview的尺寸。在我的构建方法中,我首先让 CameraView 构建其 UI 并将比例设置为 1,这意味着我只是让它在出现时自行绘制(所以不是全屏......但是)。另请注意,我将 key
设置为我的 GlobalKey
cameraControllerKey
。
在 addPostFrameCallback
方法中,我根据保存 CameraPreview 的容器视图大小和实际屏幕大小来计算比例。希望对你有帮助,快乐飘飘。///field in widget state
var cameraControllerKey = GlobalKey();
double? cameraPreviewScale;
/// In build method
if(cameraPreviewScale==null){
WidgetsBinding.instance?.addPostFrameCallback((timeStamp) {
final screenSize = MediaQuery.of(context).size;
final previewSize = cameraControllerKey.currentContext!.size!;
setState(() {
cameraPreviewScale = screenSize.width / previewSize.width;
});
});
}
return Scaffold(
key: _scaffoldKey,
body:
Stack(
fit: StackFit.loose,
children: [
Center(
child: Container(
key: cameraControllerKey,
child: Transform.scale(
alignment: Alignment.center,
scale: cameraPreviewScale ?? 1,
child: CameraPreview(cameraController!))),
),
],
)
);
FittedBox
和
SizedBox
的组合,您可以固定相机尺寸以填充整个屏幕,并保持预览准确(不拉伸)。使用以下代码片段:
FittedBox(
fit: BoxFit.fitWidth, // This ensures the width is fully covered without stretching.
child: SizedBox(
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.height,
child: CameraPreview(_controller),
),
),
让我们了解一下小部件的工作原理,以阐明其工作原理:
FittedBox
BoxFit.fitWidth
确保 CameraPreview 的宽度与屏幕的宽度相匹配。通过执行 BoxFit.fitWidth
,我们确保宽度被填充而不拉伸高度。SizedBox
的演示 并且我没有自定义 CameraPreview 的 AspectRatio(实际上我做了,但它不起作用)。
我解决的方法很简单。
return Stack(
children: [
Container(
width: double.infinity,
height: double.infinity,
child: CameraPreview(_cameraController))
],
);
我正在使用 Container 小部件的属性宽度和高度来使 CameraPreview 拉伸为全屏。
return Stack(
children: [
Positioned(
top: 0,
bottom: 0,
child: CameraPreview(_cameraController!),
),
],
);