Windows上让Qt5 QCamera响应UVC摄像头硬件按钮拍图

QCamera相机类提供了一些基本的功能,包括拍照和录制功能(Windows上不支持录制视频),但也有很多接口是没有封装的,比如有些UVC摄像头有物理按键,可以进行拍图等操作,但是QCamera没法响应硬件按钮的拍图操作。

网络上的相关代码都是直接封装平台库(如Windows的DirectShow,Linux的V4L2)来支持硬件按钮,比如我之前参考的一些:

https://www.jianshu.com/p/a67b8cfc57c5

https://gitee.com/fsfzp888/UVCCapture/

https://github.com/GoodRon/QtWebcam

https://github.com/liuleidong/UVCCaptureDemo

但是自己封装出来的效果不是太好,总有一些奇怪的BUG。后来查看Qt5文档和源码,QCamera在Windows平台也是封装的DirectShow,代码路径:

Qt\qt-everywhere-src-5.15.2\qtmultimedia\src\plugins\directshow

既然如此,想让QCamera响应硬件按钮的拍图操作,只需要修改下directshow这个插件即可,而其他的视频渲染等功能就不用自己封装了。视频预览和拍图的接口是差不多的,只需要把预览的接口复制粘贴一份稍加修改。(如果要扩展其他功能,也是直接修改相关源码即可)

先在directshowcameraglobal.h加一个GUID声明PIN_CATEGORY_STILL(因为文本不好标注哪些是新增的,所以用的截图,图中红色为新增代码):

在dscamerasession.h和cpp代码里搜m_previewSampleGrabber和m_nullRendererFilter,然后复制粘贴修改一份。有一点不同的就是,预览的接口如果操作失败是直接返回false,但是硬件拍图我们不能直接返回,因为有的相机本身就没对应的接口,直接跳过就好了。

dscamerasession.h:

dscamerasession.cpp:

DirectShowSampleGrabber::bufferAvailable信号表示有数据来了,连接该信号进行处理,然后使用imageCaptured将图片信号发送出去即可。我这里偷懒发的空图,然后在主程序里判断是否为空再主动触发一次拍图。 

    if (!m_stillSampleGrabber) {
        m_stillSampleGrabber = new DirectShowSampleGrabber(this);
        connect(m_stillSampleGrabber, &DirectShowSampleGrabber::bufferAvailable,
                this, [this](){
            qDebug()<<"Still capture bufferAvailable";
            emit imageCaptured(-1, QImage());
        });
    }
void UVCCamera::onImageCaptured(int id, const QImage &preview)
{
    //判断是否是我们在plugins里触发的
    if (preview.isNull()) {
        if (id == -1)
            capture(); //主动拍图
        return;
    }
    //... ...
}

源码我是用 qmake 编译的,directshow.pro 可以设置导出路径,不然默认会把一些文件夹生成到盘符根目录下:

MODULE_QMAKE_OUTDIR = $$PWD/bin # 默认会生成 mkspecs 文件夹
load(qt_plugin) # 源码里自带的 load
CONFIG -= create_cmake # 默认会生成 lib/cmake 文件夹
DESTDIR = $$PWD/bin # dll 输出路径

猜你喜欢

转载自blog.csdn.net/gongjianbo1992/article/details/128695982