我们可以在 flutter 中改变相机变焦点吗?

问题描述 投票:0回答:6

我在一个

Flutter
应用程序上工作,我在其中使用了
camera
插件。我想放大到
camera
预览的任意点(偏移量),例如放大到屏幕的左上角,然后为其拍照。使用
CameraContoroller.setZoomLevel()
方法放大到
camera
的中心!是否有可能实现我想要的行为?提前谢谢你!

这就是我想要实现的目标!

flutter android-camera flutter-image
6个回答
0
投票

不幸的是,相机包可能无法实现您想要的行为。这是因为相机本身无法放大其视图的特定区域,因为缩放与硬件的工作方式。

但是有一些方法可以实现您的预期行为。尝试用 OverflowBox 和/或 ClipRect 包装您的 CameraPreview 并以某种方式定位预览,只有您想要放大的部分可见。 但请注意,您实际上只是以这种方式“缩放”,因为实际的相机视图不会改变(由此产生的切口可能质量更差)。

基本上,您是通过将图像裁剪到预期区域来创建缩放的错觉。

您可以查看具体的代码示例,了解如何在this answer中实现此功能。

请记住,如果您想拍摄“缩放”区域的照片,您必须再次裁剪生成的图像(因为实际的相机视图不会改变),如上述问题中所述。


0
投票

你可以做到,但它有点不实用,通过在像

InteractiveViewer()
这样的可拖动/可缩放小部件中显示相机图像,然后用
GestureDetector()
包裹它,然后制作一个功能,当你双击图像和拖到你想要的点。


0
投票

即使在原生相机或任何其他相机上,也无法在特定视点进行相机变焦。

我检查过iphone、android甚至Dslr。由于您的相机硬件从一个分散的视角开始。如果不移动或校准相机,就不可能在特定点进行缩放。

问题只能在捕获快照并裁剪特定区域后才能解决,从而给人一种特定缩放的错觉。

然而,如果我们使用多个摄像头并从中制造出一种机制,这可以解决,唯一被忽略的原因是因为这个问题不是很重要。


0
投票

要使用相机插件在 Flutter 应用中实现您想要的行为,您可以使用 CameraController.setZoomLevel() 方法放大预览中的特定点。但是,此方法仅将缩放级别作为参数,而不是偏移量。

一种可能的解决方案是使用 Transform.scale() 小部件放大预览,然后使用 RenderRepaintBoundary.toImage() 方法以所需的偏移量捕获图像。这是一个例子:


0
投票

我正在尝试解决您的问题:

代码:

   return Listener(
        onPointerDown: (_) => _pointers++,
        onPointerUp: (_) => _pointers--,
        child: Zoom(
          maxZoomWidth: 900,
          maxZoomHeight: 900,
          child: CameraPreview(
            controller!,
            child: LayoutBuilder(
                builder: (BuildContext context, BoxConstraints constraints) {
                  return GestureDetector(
                    behavior: HitTestBehavior.opaque,
                    onScaleStart: _handleScaleStart,
                    onScaleUpdate: _handleScaleUpdate,
                    onTapDown: (TapDownDetails details) =>
                        onViewFinderTap(details, constraints),
                  );
                }),
          ),
        ),
      );

你只需要包裹

缩放

小工具

相机预览

工作正常


0
投票

是的,使用

CameraController
和一些数学可以在您的 Flutter 应用程序中实现您想要的行为。以下是您可以遵循的步骤大纲:

  1. 使用
    value.aspectRatio
    和预览大小计算相机预览的中心点。
  2. 计算要应用于相机预览的缩放系数。
  3. 计算要放大的点相对于预览中心点的偏移量。
  4. 应用缩放和偏移后计算预览的新中心点。
  5. 使用
    CameraController.setZoomLevel()
    方法将缩放系数应用到相机。
  6. 使用
    CameraController.setRotation()
    方法设置相机的旋转以考虑偏移量。
  7. 使用
    CameraController.takePicture()
    方法拍摄照片。 下面是一些示例代码,演示了如何放大相机预览的任意点:

import 'dart:math';

import 'package:camera/camera.dart';
import 'package:flutter/material.dart';

class MyCamera extends StatefulWidget {
  final List<CameraDescription> cameras;

  MyCamera({required this.cameras});

  @override
  _MyCameraState createState() => _MyCameraState();
}

class _MyCameraState extends State<MyCamera> {
  late CameraController _controller;
  late Future<void> _initializeControllerFuture;

  @override
  void initState() {
    super.initState();

    // Select the first camera from the list of available cameras
    final camera = widget.cameras.first;

    // Create a CameraController instance
    _controller = CameraController(
      camera,
      ResolutionPreset.high,
      enableAudio: false,
    );

    // Initialize the controller asynchronously
    _initializeControllerFuture = _controller.initialize();
  }

  @override
  void dispose() {
    // Dispose of the controller when the widget is disposed
    _controller.dispose();
    super.dispose();
  }

  void _takePicture() async {
    try {
      // Wait for the controller to be initialized
      await _initializeControllerFuture;

      // Calculate the center point of the preview
      final size = MediaQuery.of(context).size;
      final previewSize = _controller.value.previewSize!;
      final previewCenter = Offset(previewSize.width / 2, previewSize.height / 2);

      // Calculate the zoom factor and offset
      final zoomFactor = 2.0;
      final zoomOffset = Offset(-size.width / 4, -size.height / 4);

      // Calculate the new center point after applying the zoom and offset
      final newCenter = previewCenter.translate(zoomOffset.dx / zoomFactor, zoomOffset.dy / zoomFactor);

      // Apply the zoom and rotation to the controller
      await _controller.setZoomLevel(zoomFactor);
      await _controller.setRotation(pi / 2);

      // Wait for the camera to settle after applying the zoom and rotation
      await Future.delayed(Duration(milliseconds: 500));

      // Capture the picture
      final image = await _controller.takePicture();

      // Do something with the image
    } catch (e) {
      // Handle the error
      print(e);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('My Camera'),
      ),
      body: FutureBuilder<void>(
        future: _initializeControllerFuture,
        builder: (context, snapshot) {
          if (snapshot.connectionState == ConnectionState.done) {
            return CameraPreview(_controller);
          } else {
            return Center(child: CircularProgressIndicator());
          }
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _take

© www.soinside.com 2019 - 2024. All rights reserved.