赞
踩
1、功能概述
PyQt5多媒体模块为摄像头操作提供了几个类,可以用于获取摄像头设备信息,通过摄像头进行拍照和录像。
Qt多媒体模块的功能实现是依赖于平台的。在Windows平台上,Qt多媒体模块依赖于两个插件:一个是使用Microsoft DirectShow API的插件,DirectShow在Windows 98引入,在Windows XP以后就逐渐过时了;另一个是Windows Media Foundation(WMF)的插件,WMF插件在Windows Vista引入,用于替代DirectShow。
Qt中的WMF插件目前无法提供摄像头支持,对摄像头的有限支持是由DirectShow插件提供的,目前只能显示取景器和抓取静态图片,其他大部分功能不支持。所以,目前在Windows平台上,Qt的摄像头控制不支持视频录制功能,也不支持底层的视频功能,例如使用QVideoProbe探测视频帧。
PyQt5的多媒体模块在Windows平台上也无法实现摄像头录像功能。
2、主要类与函数
++++++++++++++++++++++++++++
QCameraInfo:摄像头设备信息类
availableCameras():返回QCameraInfo类型的列表,表示系统可用的摄像头。
defaultCamera():返回一个QCameraInfo对象,是系统默认的摄像头设备信息。
description():返回摄像头设备描述。
deviceName():返回摄像头设备名称。
position():返回值是枚举类型QCamera.Position,表示摄像头的位置。
例如手机一般有两个摄像头,前置摄像头位置类型为QCamera.FrontFace,后置摄像头位置类型为QCamera.BackFace,未指定位置的是QCamera.UnspecifiedPosition。
++++++++++++++++++++++++++++
QCamera:操作摄像头的类,创建QCamera对象时需传递一个QCameraInfo对象作为参数。
setViewfinder(viewfinder):为摄像头指定一个QVideoWidget或QGraphicsVideoItem对象viewfinder作为取景器,用于摄像头图像预览。一般使用一个QCameraViewfinder类对象用于摄像头预览,其父类是QVideoWidget。
setCaptureMode(mode):用于设置摄像头工作模式,参数mode是枚举类型QCamera. CaptureModes,有以下几种取值:
QCamera.CaptureViewfinder(取景器模式,摄像头仅用于预览);
QCamera.CaptureStillImage(抓取静态图片模式);
QCamera.CaptureVideo(视频录制模式)。
isCaptureModeSupported(mode),判断摄像头是否支持某种工作模式,参数mode是枚举类型QCamera.CaptureModes。
searchAndLock():拍照之前执行,用于在快门半按下时锁定摄像头的曝光、白平衡等参数
unlock():拍照后执行,用于解除锁定。
++++++++++++++++++++++++++++
QCameraImageCapture:控制摄像头进行静态图片的抓取
setEncodingSettings(settings):设置拍照图片的编码,settings是QImageEncoderSettings类型,设置内容包括编码方案、分辨率、图片质量等。
setBufferFormat(format):设置拍照缓冲区的图片的格式,参数format是枚举类型QVideoFrame.PixelFormat,有几十种取值,这里用QVideoFrame.Format_Jpeg,也就是使用JPEG格式。
setCaptureDestination(destination):用于设置所拍摄图片的保存方式,destination是枚举类型QCameraImageCapture.CaptureDestination,有以下两种取值:
QCameraImageCapture.CaptureToBuffer(拍摄的图片保存在缓冲区里,会发射信号
imageCaptured(),在此信号的槽函数里可以提取缓冲区中的图片); - QCameraImageCapture.CaptureToFile(拍摄的图片自动保存文件到用户目录的“图片”
文件夹里,保存图片后会发射imageSaved()信号)。 如果设置为CaptureToBuffer,就只会发射imageCaptured()信号,图片出现在缓冲区,不会自动保存为文件,也不会发射imageCaptured()信号;而如果设置为CaptureToFile,两个信号都会被发射。
QCameraImageCapture的3个信号及关联的槽函数的作用如下。
readyForCaptureChanged(ready):信号在摄像头是否可以拍照的状态变化时发射,bool型参数ready正好用于控制拍照按钮的使能状态。
imageCaptured(imageID, preview)在图像被抓取到缓冲区后发射,imageID是图像的编号,每次拍照时自动累加,preview是QImage类型,是拍摄的图片。在关联的槽函数里,将此图片的内容显示到界面上的QLabel组件LabImage上。
imageSaved(imageID, fileName)信号在图片保存为文件后发射,fileName是自动保存的文件名称。在关联的槽函数里显示了imageID和文件名fileName。
++++++++++++++++++++++++++++
QMediaRecorder:通过摄像头和音频输入设备进行视频录制
3、代码实现
这个窗口工作区的左侧是摄像头预览显示,是一个QCameraViewfinder组件,右侧是拍摄照片的显示,是一个QLabel组件。两个GroupBox组件之间使用了分割布局。
from PyQt5.QtGui import QImage,QPixmap from PyQt5.QtMultimedia import (QCameraInfo,QCameraImageCapture, QImageEncoderSettings,QMultimedia,QVideoFrame,QSound,QCamera) from ui_MainWindow import Ui_MainWindow class QmyMainWindow(QMainWindow): def __init__(self, parent = None): super().__init__(parent) #调用父类构造函数,创建窗体 self.ui = Ui_MainWindow() #创建UI对象 self.ui.setupUi(self) #构造UI界面 self.__LabCameraState = QLabel("摄像头state:") self.__LabCameraState.setMinimumWidth(150) self.ui.statusBar.addWidget(self.__LabCameraState) self.__LabImageID = QLabel("图片文件ID:") self.__LabImageID.setMinimumWidth(100) self.ui.statusBar.addWidget(self.__LabImageID) self.__LabImageFile = QLabel("") #保存的图片文件名 self.ui.statusBar.addPermanentWidget(self.__LabImageFile) self.camera = None #QCamera对象 cameras = QCameraInfo.availableCameras() #list[QCameraInfo] if len(cameras)>0: self.__iniCamera() #初始化摄像头 self.__iniImageCapture() #初始化静态画图 self.camera.start() ## ==============自定义功能函数======================== def __iniCamera(self): ##创建 QCamera对象 camInfo=QCameraInfo.defaultCamera() #获取缺省摄像头,QCameraInfo self.ui.comboCamera.addItem(camInfo.description()) #摄像头描述 self.ui.comboCamera.setCurrentIndex(0) self.camera=QCamera(camInfo) #创建摄像头对象 self.camera.setViewfinder(self.ui.viewFinder) #设置取景框预览 ## camera.setCaptureMode(QCamera.CaptureViewfinder) #预览 self.camera.setCaptureMode(QCamera.CaptureStillImage) #设置为抓图 ## camera.setCaptureMode(QCamera.CaptureVideo) mode=QCamera.CaptureStillImage supported=self.camera.isCaptureModeSupported(mode) self.ui.checkStillImage.setChecked(supported) #支持拍照 supported=self.camera.isCaptureModeSupported(QCamera.CaptureVideo) self.ui.checkVideo.setChecked(supported) #支持视频录制 supported=self.camera.exposure().isAvailable() self.ui.checkExposure.setChecked(supported) #支持曝光补偿 supported=self.camera.focus().isAvailable() self.ui.checkFocus.setChecked(supported) #支持变焦 self.camera.stateChanged.connect(self.do_cameraStateChanged) def __iniImageCapture(self): ##创建 QCameraImageCapture对象 self.capturer = QCameraImageCapture(self.camera) settings=QImageEncoderSettings() #拍照设置 settings.setCodec("image/jpeg") #设置抓图图形编码 settings.setResolution(640, 480) #分辨率 settings.setQuality(QMultimedia.HighQuality) #图片质量 self.capturer.setEncodingSettings(settings) self.capturer.setBufferFormat(QVideoFrame.Format_Jpeg) #缓冲区格式 if self.ui.chkBoxSaveToFile.isChecked(): dest=QCameraImageCapture.CaptureToFile #保存到文件 else: dest=QCameraImageCapture.CaptureToBuffer #保存到缓冲区 self.capturer.setCaptureDestination(dest) #保存目标 self.capturer.readyForCaptureChanged.connect(self.do_imageReady) self.capturer.imageCaptured.connect(self.do_imageCaptured) self.capturer.imageSaved.connect(self.do_imageSaved) ## ==============event处理函数========================== ## ==========由connectSlotsByName()自动连接的槽函数============ @pyqtSlot(bool) ##设置保存方式 def on_chkBoxSaveToFile_clicked(self,checked): if checked: dest=QCameraImageCapture.CaptureToFile #保存到文件 else: dest=QCameraImageCapture.CaptureToBuffer #保存到缓冲区 self.capturer.setCaptureDestination(dest) #保存目标 @pyqtSlot() ##拍照 def on_actCapture_triggered(self): QSound.play("shutter.wav") #播放快门音效 self.camera.searchAndLock() #快门半按下时锁定摄像头参数 self.capturer.capture() #拍照 self.camera.unlock() #快门按钮释放时解除锁定 @pyqtSlot() ##打开摄像头 def on_actStartCamera_triggered(self): self.camera.start() @pyqtSlot() ##关闭摄像头 def on_actStopCamera_triggered(self): self.camera.stop() ## =============自定义槽函数=============================== def do_cameraStateChanged(self,state): ##摄像头状态变化 if (state==QCamera.UnloadedState): self.__LabCameraState.setText("摄像头state: UnloadedState") elif (state==QCamera.LoadedState): self.__LabCameraState.setText("摄像头state: LoadedState") elif (state==QCamera.ActiveState): self.__LabCameraState.setText("摄像头state: ActiveState") self.ui.actStartCamera.setEnabled(state!=QCamera.ActiveState) self.ui.actStopCamera.setEnabled(state==QCamera.ActiveState) def do_imageReady(self,ready): ##是否可以拍照了 self.ui.actCapture.setEnabled(ready) def do_imageCaptured(self,imageID,preview): ##图片被抓取到内存 #preview是 QImage H=self.ui.LabImage.height() W=self.ui.LabImage.width() scaledImage = preview.scaled(W,H, Qt.KeepAspectRatio, Qt.SmoothTransformation) self.ui.LabImage.setPixmap(QPixmap.fromImage(scaledImage)) self.__LabImageID.setText("图片文件ID:%d"%imageID) self.__LabImageFile.setText("图片保存为: ") def do_imageSaved(self,imageID,fileName): ##图片被保存 self.__LabImageID.setText("图片文件ID:%d"%imageID) self.__LabImageFile.setText("图片保存为: "+fileName) ## ============窗体测试程序 ================================ if __name__ == "__main__": #用于当前窗体测试 app = QApplication(sys.argv) #创建GUI应用程序 form=QmyMainWindow() #创建窗体 form.show() sys.exit(app.exec_())
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。