首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QPixmap不能抓取web浏览器窗口

QPixmap不能抓取web浏览器窗口
EN

Stack Overflow用户
提问于 2017-07-10 00:15:31
回答 1查看 189关注 0票数 1

当我在web浏览器窗口中使用QPixmap::GrabWindow(WId)时,它只返回黑屏。

我使用了以下代码:

代码语言:javascript
复制
QScreen *screen = QGuiApplication::primaryScreen();
m_pixmap = screen->grabWindow(hW);
m_image = m_pixmap.toImage();
m_image.save("p.png");

当我打开"p.png“时,它只是一张黑色的图片。对于其他窗口,这一点工作得很好。

如何获取浏览器的正常屏幕?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-05 20:08:58

事实上,QScreen ::grabWindow使用Windows GDI来捕获图像。这是一个相当古老的API,由没有硬件加速(由处理器绘制)的程序使用。和铬-软件并不古老,很久以前就是通过Windows DXGI绘制的。

我已经编写了使用这种技术的软件。发布了示例代码here。它将由MSVC编译器在Qt 5.10库上编译,看起来没有区别,2015或2017年。我的机器是64位的,也许这也很重要。

里面有两个类: FrameBroadcast和FrameCapturer。FrameBroadcast以一定的时间间隔向FrameCapturer请求屏幕截图,并通过信号void frameCaptured (QSharedPointer <Frame> frame); QSharedPointer自动删除分配给屏幕内容的内存,一旦内存超出所有插槽处理程序的范围,就会发送给订户。

代码语言:javascript
复制
#include <QApplication>
#include <QObject>
#include <QPixmap>
#include <QImage>
#include <QDialog>
#include <QLabel>

#include "framebroadcast.h"

/*static Frame* CopyFrame(const Frame *incomingFrame)
{
    Frame *frame = new Frame();
    frame->width=incomingFrame->width;
    frame->height=incomingFrame->height;
    frame->lenght=incomingFrame->lenght;
    frame->buffer=new unsigned char[frame->lenght];

    std::memcpy(frame->buffer,incomingFrame->buffer,frame->lenght);
    return frame;
}

static Frame* CopyFrame(const QSharedPointer<Frame> &incomingFrame)
{
    return CopyFrame(incomingFrame.data());
}*/


int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QDialog *dialog = new QDialog();
    QLabel *label = new QLabel(dialog);

    FrameBroadcast *cast = new FrameBroadcast();
    QObject::connect(cast, &FrameBroadcast::frameCaptured, [=](const QSharedPointer<Frame> &frame) {

        int w = static_cast<int>(frame.data()->width);
        int h = static_cast<int>(frame.data()->height);

        QImage img(frame.data()->buffer,w,h,QImage::Format_RGBA8888);
        label->setPixmap(QPixmap::fromImage(img));
        label->resize(w,h);

        qDebug() << "Update";
    });
    cast->startCapture();

    dialog->show();

    return app.exec();
}

在main.cpp中,将创建一个简单的对话框,其中显示捕获的结果。为了以防万一,我附加了一段代码,用于在不可能将所有操作放在一个插槽中时,将屏幕内容从QSharedPointer中解开。它紧跟在inclusions之后,并被注释掉。

代码语言:javascript
复制
#pragma comment(lib,"dxgi.lib")
#pragma comment(lib,"D3D11.lib")
#pragma comment(lib,"Shcore.lib")
#pragma comment(lib,"winmm.lib")
#pragma comment(lib,"windowscodecs.lib")
#pragma comment (lib, "user32.lib")
#pragma comment (lib, "dxguid.lib")

详细解析代码是没有意义的。它太大了,但它不会很难重新包装,以满足您的需求。值得注意的是,使用了"Auto-linking“-微软编译器的特性:必要的库将在编译时自动启动(参见framecapturer.h)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/44998473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档