Camera Overview

Qt Multimedia API提供许多与摄像头相关的类, 因此你可以访问移动设备的摄像头或网络摄像头的图片和视频. 这部分既有C++ API, 也有QML API.

摄像头功能

为了使用摄像头类, 需要快速概述摄像头的工作方式. 如果你已经熟悉这一点, 可以跳到 摄像头实现的详细信息.

镜头组件

在摄像头的一端是镜头组件 (一个或多个透镜, 将光聚焦到传感器上). 镜头可以移动, 调整焦点或变焦; 也可以固定.

有些镜头可以自动调整, 自动对焦不同距离的物体. 这是通过测量特定区域的锐利程度, 并调整焦点, 使其达到最大锐度. 一些情况下, 摄像机始终以帧中心进行此操作. 某些相机可以指定聚焦区域 (用于 "触摸缩放", 或 "面部缩放" 功能).

传感器

光线到达传感器后, 它会转换成数字像素. 这个处理过程受多种因素影响, 但可以归结为两件事--转换时间的长短, 光线的亮度. 转换时间越长, 质量越好. 使用闪光灯将更多光线照射到传感器上, 使其更快转换像素, 在相同的时间得到更好的质量.相反, 在黑暗的环境下, 只要相机稳定, 只要有更长的转换时间也可以拍摄画面.

图像处理

传感器捕获到图像后, 相机固件对图像进行处理, 补偿各种传感器特性, 光照和期望的图像特性. 更快的传感器像素转换时间往往会引入数字噪声, 图像处理流程可以根据传感器设置消除这种噪声.

这个阶段, 还可以调整图像颜色, 补偿不同光源(荧光灯, 阳光)给同一物体带来不同的外观, 根据图像的白平衡(光源的色温不同)调整图像.

一些 "特效" 也是在这个阶段添加. 黑白, 复古, 或 "负面" 风格图像.

后续处理

创建一个完美聚焦, 曝光的图像后, 你就可以很好利用它. 图像可以通过其他应用程序对其进行进一步处理(如, 检测条形码或将全景图像拼接在一起), 或保存为JPEG等常见格式, 或创建电影.

摄像头实现细节

检测选择摄像头

使用摄像头API前, 你应该检查摄像头是否可用. 如果没有可用摄像头, 你可用禁用应用程序中与摄像头相关的功能. 如下所示, 调用 QCameraInfo::availableCameras() 函数检测摄像头是否可用:


  bool checkCameraAvailability()
  {
      if (QCameraInfo::availableCameras().count() > 0)
          return true;
      else
          return false;
  }

在QML中, 使用 QtMultimedia.availableCameras 属性判断:


  Item {
      property bool isCameraAvailable: QtMultimedia.availableCameras.length > 0
  }

检测完摄像头是否可用之后, 在C++中, 你可以使用 QCamera 访问摄像头; 在QML中, 你可以使用 Camera 类型.

如果系统有多个摄像头可用时, 你可以采用如下方式使用其中的某个摄像头.

In C++:


  QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
  foreach (const QCameraInfo &cameraInfo, cameras) {
      if (cameraInfo.deviceName() == "mycamera")
          camera = new QCamera(cameraInfo);
  }

在QML中, 你可以设置 CameradeviceId属性. 所有的可用ID都从 QtMultimedia.availableCameras获取:


  Camera {
      deviceId: QtMultimedia.availableCameras[0].deviceId
  }

你还可以根据摄像头在系统的物理位置选择摄像头. 这点在移动设备上很有用, 因为移动设备通常有前置摄像头和后置摄像头.

C++代码:


  camera = new QCamera(QCamera::FrontFace);

QML代码:


  Camera {
      position: Camera.FrontFace
  }

如果既没有指定设备ID, 又没有指定位置, 将使用默认摄像头. 在PC机上, 默认摄像头由用户在系统设置中设置. 在移动设备上, 背面摄像头通常是默认摄像头. 在C++中, 你可以调用 QCameraInfo::defaultCamera() 获取默认摄像头信息; 在QML中使用 QtMultimedia.defaultCamera.

取景器

虽然不是绝对必要的, 但是能够看到摄像头的内容很有用. 大部分数码相机允许以较低分辨率(通常是相机显示器的大小)提供图像, 这样你可以合成照片或视频, 然后切换到较慢, 分辨率较高的模式拍摄图像.

不论你采用QML还是C++, 你有多种方式实现取景器. 在QML中, 你可以使用 CameraVideoOutput 组合实现一个简单的取景器:


  VideoOutput {
      source: camera

      Camera {
          id: camera
          // You can adjust various settings in here
      }
  }

在C++中, 你可以使用QCameraViewfinderQGraphicsVideoItem( QGraphicsView).


  camera = new QCamera;
  viewfinder = new QCameraViewfinder;
  camera->setViewfinder(viewfinder);
  viewfinder->show();

  camera->start(); // to start the viewfinder

对于高级用途(如处理视频帧, 检测对象或图像), 你也可以从 QAbstractVideoSurface 派生, 并设置为 QCamera 对象的取景器. 在这种情况下, 你需要自己渲染取景器图像.


  camera = new QCamera;
  mySurface = new MyVideoSurface;
  camera->setViewfinder(mySurface);

  camera->start();
  // MyVideoSurface::present(..) will be called with viewfinder frames

在移动设备上, 取景器图像可能并不处于你所期望的方向. 设备上的摄像头传感器通常横向安装, 而屏幕的自然方向是纵向. 这会导致图像出现在侧方或倒置, 具体取决于设备方向. I为了在屏幕上显示用户实际看到的内容, 你应该确保取景器始终旋转到正确方向, 并考虑摄像头传感器的方向和当前显示方向.


  // Assuming a QImage has been created from the QVideoFrame that needs to be presented
  QImage videoFrame;
  QCameraInfo cameraInfo(camera); // needed to get the camera sensor position and orientation

  // Get the current display orientation
  const QScreen *screen = QGuiApplication::primaryScreen();
  const int screenAngle = screen->angleBetween(screen->nativeOrientation(), screen->orientation());

  int rotation;
  if (cameraInfo.position() == QCamera::BackFace) {
      rotation = (cameraInfo.orientation() - screenAngle) % 360;
  } else {
      // Front position, compensate the mirror
      rotation = (360 - cameraInfo.orientation() + screenAngle) % 360;
  }

  // Rotate the frame so it always shows in the correct orientation
  videoFrame = videoFrame.transformed(QTransform().rotate(rotation));

图像

设置完取景器, 准备拍摄图像时, 我们需要创建并初始化一个 QCameraImageCapture 对象.然后启动摄像头, 锁定摄像头, 拍照, 最后解锁摄像头, 为下次拍照做好准备.


  imageCapture = new QCameraImageCapture(camera);

  camera->setCaptureMode(QCamera::CaptureStillImage);
  camera->start(); // Viewfinder frames start flowing

  //on half pressed shutter button
  camera->searchAndLock();

  //on shutter button pressed
  imageCapture->capture();

  //on shutter button released
  camera->unlock();

视频

录制视频需要使用 QMediaRecorder 对象.

录制视频时, 先创建一个QCamera对象, 再创建并初始化一个QMediaRecorder对象.


  camera = new QCamera;
  recorder = new QMediaRecorder(camera);

  camera->setCaptureMode(QCamera::CaptureVideo);
  camera->start();

  //on shutter button pressed
  recorder->record();

  // sometime later, or on another press
  recorder->stop();

连接 mediaRecorder 信号, 接收记录器状态变化, 并处理错误事件. 调用 record() 函数, 会发出 stateChanged() 信号. 调用QMediaRecorder的槽函数 record(), stop()setMuted() 更改录制过程.

控制成像管道

介绍完捕获图像或视频的基础知识后, 我们有多种方法控制成像管道, 实现一些有趣的技术. 如前所述, 几个物理和电子元件结合起来确定最终图像, 你可以用不同的类控制它们.

对焦和缩放

对焦(和缩放)主要由 QCameraFocus 管理. QCameraFocus 允许开发人员通过 FocusModeFocusPointMode设置一些策略. FocusMode 包括 AutoFocus, ContinuousFocusInfinityFocus, FocusPointMode 设置对焦区域. FocusPointMode 支持人脸识别(需要相机支持), 中心对焦和自定义焦点.

对于支持微距对焦的相机硬件, 微距对焦允许对传感器附近的事物成像. 这在条形码识别或名片扫描等应用程序中非常有用.

除对焦外, QCameraFocus 允许你控制任何可用的光学或数字对焦. 一般而言, 光学变焦质量更高, 但制作成本更高, 因此可用的变焦范围很有限(或为固定单位).

曝光, 光圈, 快门速度和闪光灯

很多设置会影响照射到摄像头传感器的光量, 从而影响生成图像的质量. QCameraExposure 允许你调整这些设置实现一些效果, 如锁定曝光参数(QCamera::searchAndLock()实现高动态范围(HDR)照片), 或设置小光圈的慢快门速度实现运动模糊.

自动图像拍摄有 曝光模式闪光灯模式. 其他一些设置(光圈, ISO设置, 快门速度)通常是自动管理的, 但如果需要, 也可以覆盖.

你也可以调整 QCameraExposure::meteringMode() 控制摄像头框架的哪些部分测量曝光. 一些摄像头实现还允许你指定用于曝光测量的特定点-如果你可以让用户触摸或点击取景器中的感兴趣的部分, 这很有用. 使用这个点, 使图像在这个点的质量最佳.

最后, 你可以使用这个类控制闪光灯(若有). 在某些情况下, 闪光灯也兼做手电筒(闪光灯基于LED, 而不是氙气或其他灯泡). 参见 手电筒, 了解如何使用API.

图像处理

QCameraImageProcessing 调整管道中的图像处理部分, 包括 白平衡 (或色温), 对比度, 饱和度, 锐化去噪. 多数摄像头自动配置这些属性, 因此, 除非用户想做特定设置, 你不需要关注这部分内容.

如果你正在拍摄一系列图像(如, 拼接全景图像的一组图像),那么你应该调用 QCamera::lock(QCamera::LockWhiteBalance)锁定图像处理设置, 使所有图像效果一致.

取消异步操作

诸如图像捕获和自动对焦之类的异步操作, 若摄像头支持, 这些操作都可以取消. 对于图像捕获, 调用 cancelCapture()取消. 对于自动对焦, 调用 QCamera::unlock(QCamera::LockFocus)取消自动曝光或白平衡.

示例

There are both C++ and QML examples available.

C++ Examples

QML Examples

参考文档

C++ Classes

QCamera::FrameRateRange

A FrameRateRange represents a range of frame rates as minimum and maximum rate

QCamera

Interface for system camera devices

QCameraExposure

Interface for exposure related camera settings

QCameraFocus

Interface for focus and zoom related camera settings

QCameraFocusZone

Information on zones used for autofocusing a camera

QCameraImageCapture

Used for the recording of media content

QCameraImageProcessing

Interface for image processing related camera settings

QCameraInfo

General information about camera devices

QCameraViewfinderSettings

Set of viewfinder settings

QImageEncoderSettings

Set of image encoder settings

QML Types

Camera

Access viewfinder frames, and take photos and movies

CameraCapture

An interface for capturing camera images

CameraExposure

An interface for exposure related camera settings

CameraFlash

An interface for flash related camera settings

CameraFocus

An interface for focus related camera settings

CameraImageProcessing

An interface for camera capture related settings

CameraRecorder

Controls video recording with the Camera