到目前为止,我一直在四处奔波,我很喜欢它,但我在让相机工作时遇到了问题。
我按照此页https://pub.dartlang.org/packages/camera上的说明进行操作。但是,相机被拉伸以适应手机屏幕,但图像翘曲并且比应有的高。使用相机的其他应用程序似乎保持比例,有没有办法确保它不会拉伸但仍然填满屏幕?
答案 0 :(得分:13)
在lase解决方案的基础上,即使设备的纵横比与摄像头的纵横比不同,此方法也可以工作:
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Transform.scale(
scale: controller.value.aspectRatio / deviceRatio,
child: Center(
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
),
),
);
答案 1 :(得分:7)
好吧,受以前的帖子启发,我让它可以在具有不同屏幕纵横比的2个屏幕上工作。我要做的是打印值并寻找差异(与您所谓的受过良好教育的方法完全不同)。结果是,一个屏幕比另一个屏幕高,尽管宽度相同,所以屏幕的长宽比也不同。
免责声明:这是在锁定了纵向的应用中进行的测试,但不能保证该功能可以横向使用。另外,这似乎确实会将某些相机预览像素放置在屏幕之外,但目前我还没有补救措施。
无论选择哪种摄像机分辨率,摄像机控制器的宽高比均保持不变,但是屏幕的宽高比有所不同,因此较早的文章中提到的计算适用于一个(较短)的屏幕,但不适用于另一个(taller)的屏幕
经过长时间的计算,很明显,要填充整个屏幕,比例因子必须大于1。因此,最后,要使该比例在两个屏幕上都可以使用,必须检查是否一个比率大于另一个比率并切换操作数,以得到大于1的比例因子。
这是更改的内容,最终结果:
Widget cameraWidget(context) {
// get screen size
final size = MediaQuery.of(context).size;
// calculate scale for aspect ratio widget
var scale = _cameraController.value.aspectRatio / size.aspectRatio;
// check if adjustments are needed...
if (_cameraController.value.aspectRatio < size.aspectRatio) {
scale = 1 / scale;
}
return Transform.scale(
scale: scale,
child: Center(
child: AspectRatio(
aspectRatio: _cameraController.value.aspectRatio,
child: CameraPreview(_cameraController),
),
),
);
}
请注意,缩放比例必须大于1才能填满整个屏幕。
Screen size (w/h): Size(411.4, 797.7)
Screen size aspect ratio: 0.515759312320917
Controller preview size: Size(1280.0, 720.0)
Controller aspect ratio: 0.5625
Scale: 1.0906249999999997
Screen size (w/h): Size(411.4, 683.4)
Screen size aspect ratio: 0.6020066889632107
Controller preview size: Size(1280.0, 720.0)
Controller aspect ratio: 0.5625
Scale: 1.0702341137123745
Screen size (w/h): Size(411.4, 683.4)
Screen size aspect ratio: 0.6020066889632107
Controller preview size: Size(1280.0, 720.0)
Controller aspect ratio: 0.5625
Scale: 0.934375
答案 2 :(得分:5)
我遇到了类似的问题,虽然理查德的答案很有帮助,但我也遇到了预览太小的问题。可能有更好的方法,但我能够通过像这样的宽高比反转来缩放它来解决它:
return new Scaffold(
appBar: new AppBar(title: new Text('Capture')),
body: new Transform.scale(
scale: 1 / controller.value.aspectRatio,
child: new Center(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller)),
)),
);
从内到外,这应该:
CameraPreview
答案 3 :(得分:1)
您需要将预览包装在提供正确宽高比的窗口小部件中 - 通过自己将宽度和高度设置为正确的比例,或使用AspectRatio。例如,相机插件示例使用:
$f
答案 4 :(得分:1)
我只想基于Marek Lisy的答案,因为它确实破坏了容器。就我而言,我使用的是TabBarView,但该答案会导致不正确地捕捉到选项卡。我使用ClipRect修复了此问题,如下所示:
final size = MediaQuery.of(context).size;
if (!controller.value.isInitialized) {
return Container();
}
return ClipRect(
child: Container(
child: Transform.scale(
scale: controller.value.aspectRatio / size.aspectRatio,
child: Center(
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
),
),
),
),
);
最幸运的家伙!我花了一个小时左右的时间来解决这个问题。因此,希望没有人遇到相同的问题。
答案 5 :(得分:0)
这是我想出的(仅在纵向模式下):
Map<String, double> ratios = {
'1:1': 1 / 1,
'9:16': 9 / 16,
'3:4': 3 / 4,
'9:21': 9 / 21,
'full': MediaQuery.of(context).size.aspectRatio,
};
final size = MediaQuery.of(context).size;
print('screen ratio: ${size.aspectRatio}, default: $_defaultRatio');
return Transform.scale(
scale: 1.0,
child: AspectRatio(
aspectRatio: _defaultRatio,
child: OverflowBox(
alignment: Alignment.center,
child: FittedBox(
fit: size.aspectRatio >= _defaultRatio
? BoxFit.fitHeight
: BoxFit.fitWidth,
child: Container(
width: size.aspectRatio >= _defaultRatio
? size.height
: size.width,
height: size.aspectRatio >= _defaultRatio
? size.height / controller.value.aspectRatio
: size.width / controller.value.aspectRatio,
child: Stack(
children: <Widget>[
CameraPreview(controller),
],
),
),
),
),
),
);
答案 6 :(得分:0)
在我的情况下,我应用了RotatedBox()。 下面的代码运行完美:
ggplot(data = data2) + scale_y_reverse(limits = c(1000, 0)) +
scale_x_continuous(limits = c(0, 200)) +
geom_point(aes(y = Depth, x = C_flux_umol, fill = SampleType, shape = TrapType),
colour = "black", stroke = 1, size = 5) +
#geom_point(aes(x = tot_flux2)) +
scale_shape_manual(values = c(25, 22))+
scale_size_manual(values = c(3, 4)) +
ylab("Depth (m)") + xlab("Flux micro-mol/m^2/day") +
guides(fill = guide_legend(override.aes = list(shape = 25))) +
theme_cowplot() +
theme(legend.position = c(0.5, 0.4),
legend.box.background = element_rect(color = "black", size = .5))
我使用了“ package:camera / camera.dart ”; 您唯一需要考虑的就是“ 3:0”参数。 3-表示您的盒子转动了几圈(顺时针)。三-表示系统按钮在右侧。第二个0-这就是如何在窗口上缩放预览(现在是拉伸)。您可能需要增加灵活性,并从设备读取实际位置并更改这些数字。 我使用了其他汽车覆盖物,以查看如何将汽车放置在相机的前部以将照片发布到广告中。板。 []
答案 7 :(得分:0)
编辑:下面的方法效果很好,但是将FittedBox和SizedBox一起使用会更好。参见this video from the flutter devs。
FittedBox(child: SizedBox(child: texture, width: imageWidthInPixels, height: imageHeightInPixels));
执行此操作的最佳方法是遵循Widget of the week video on AspectRatio中的说明。使用AspectRatio确保视频保持其宽高比(如图)。然后将其包裹在Align中,然后展开。如果您使用RotatedBox调整方向,请在Align中将宽高比包装在其中。
Expanded(
child:Align(
child:AspectRatio(
child:texture, aspectRatio:cameraAspectRatio)
答案 8 :(得分:0)
我在横向时也遇到了相同的问题,我通过上下文内部的以下源代码解决了这个问题-
if (!_cameraController.value.isInitialized) {
return Container();
}
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
double xScale = _cameraController.value.aspectRatio / deviceRatio;
final yScale = 1.0;
if (MediaQuery.of(context).orientation == Orientation.landscape) {
xScale = 1.0;
}
,这样,小部件视图就这样对齐了,我在OnePlus 6 (29 Q)
和Asus Z010D (23 Marshmallow)
Android OS版本上进行了测试,并且运行良好。
RotatedBox(
quarterTurns: MediaQuery.of(context).orientation == Orientation.landscape ? 3 : 0,
child: Container(
child: AspectRatio(
aspectRatio: deviceRatio,
child: Transform(
alignment: Alignment.center,
transform: Matrix4.diagonal3Values(xScale, yScale, 1),
child: CameraPreview(_cameraController),
),
),
),
),
希望这会对某人有所帮助。
答案 9 :(得分:0)
缩放已经过重新设计,因此您不必使用其他插件来制作任何技巧: camera awesome
答案 10 :(得分:0)
在花了很长时间试图找到一种方法来解决这个问题后,我转向了这个包 https://pub.dev/packages/camerawesome 并节省了很多时间。
答案 11 :(得分:-1)
我只想补充一点,如果将相机预览放置在中心位置并且不是全屏,那么将相机的分辨率更改为veryHigh
肯定会使其全屏。
CameraController(
cameras[0],
ResolutionPreset.veryHigh
)
答案 12 :(得分:-1)
我尝试了所有解决方案,但在某些情况下所有解决方案都存在问题,请尝试一下,它的工作原理就像是一种魅力:
第一:
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
然后:
return Transform.scale(
scale: 1,
child: Center(
child: AspectRatio(
aspectRatio: deviceRatio,
child: CameraPreview(_cameraController),
),
),
);
希望对您有帮助...