QPixmap值LoadFromData

函数原型:

	bool	loadFromData(const uchar * data, uint len, const char * format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor)
	bool	loadFromData(const QByteArray & data, const char * format = 0, Qt::ImageConversionFlags flags = Qt::AutoColor)
这两个函数是根据内存中的图像数据进行导入的,而图像的数据可以是从本地磁盘上读入的文件。比如读入一张BMP格式的文件到QByteArray对象中,再调用该函数,那么该函数就会根据QByteArray中数据进行解析,分析图像的格式等。BMP文件数据包含:BITMAPFILEHEADER + BITMAPINFOHEADER + [调色板] + 图像数据。因此只要QByteArray对象中包含了这些图形所必须的信息,那么该函数就会导入成功。另外,我们有时也可以不用从磁盘上导入数据,直接在程序中按照指定的图像格式来构造图像数据,并填入QByteArray中,那么用该函数同样可以导入成功!

以下是将截屏数据填入QPixmap对象中:

void MainWindow::on_pushButton_clicked()
{
    char * pData = new char[10 * 1024 * 1024];
    HWND hWnd = GetDesktopWindow();
    HDC hDc, hDcMem;
    HBITMAP hBitmap, hOldBitmap;
    hDc = GetDC(hWnd);

    hDcMem = CreateCompatibleDC(hDc);
    RECT rectClient;
    GetClientRect(hWnd, &rectClient);
    hBitmap = CreateCompatibleBitmap(hDc, rectClient.right - rectClient.left, (rectClient.bottom - rectClient.top));
    hOldBitmap = (HBITMAP)SelectObject(hDcMem, hBitmap);

    BITMAP bitmap;
    GetObject(hBitmap, sizeof(BITMAP), &bitmap);

    BITMAPINFOHEADER bitmapInfoHeader;
    memset(&bitmapInfoHeader, 0, sizeof(bitmapInfoHeader));
    bitmapInfoHeader.biBitCount = bitmap.bmBitsPixel;
    bitmapInfoHeader.biWidth = bitmap.bmWidth;
    bitmapInfoHeader.biHeight = -bitmap.bmHeight;
    bitmapInfoHeader.biPlanes = 1;
    bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
    bitmapInfoHeader.biSizeImage = bitmap.bmWidthBytes * bitmap.bmHeight;
    bitmapInfoHeader.biCompression = BI_RGB;

    BitBlt(hDcMem, 0, 0, rectClient.right - rectClient.left, rectClient.bottom - rectClient.top, hDc, 0, 0, SRCCOPY);

    int lines;
    lines = GetDIBits(hDcMem, hBitmap, 0, bitmap.bmHeight, pData + sizeof(BITMAP), (LPBITMAPINFO)&bitmapInfoHeader, DIB_RGB_COLORS);  //写入图像信息

    BITMAPFILEHEADER bitmapFileHeader;
    bitmapFileHeader.bfReserved1 = 0;
    bitmapFileHeader.bfReserved2 = 0;
    bitmapFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bitmapInfoHeader.biSizeImage;
    bitmapFileHeader.bfType = 0x4d42;
    bitmapFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);

    QByteArray byteArray;
    byteArray.append((char*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));    //文件信息头
    byteArray.append((char*)&bitmapInfoHeader,sizeof(BITMAPINFOHEADER));    //位图信息头
    byteArray.append(pData,bitmapInfoHeader.biSizeImage);                   //位图信息数据
    qDebug()<<byteArray.size();

    bool bRet = false;
    QPixmap pixmap;
    //bRet = pixmap.loadFromData(byteArray);        //导入方式1
    bRet = pixmap.loadFromData((const uchar*)byteArray.data(),byteArray.size());    //导入方式2
    qDebug()<<"LoadFromData:"<<bRet;
    m_pixmap = pixmap;

    SelectObject(hDcMem, hOldBitmap);
    DeleteObject(hDcMem);
    ReleaseDC(hWnd, hDc);
    DeleteObject(hBitmap);
    delete[] pData;

    update();
}


void MainWindow::paintEvent(QPaintEvent *)
{
    static int i = 0;
    qDebug()<<"begin draw"<<i++;
    if(!m_pixmap.isNull())
    {
        QPainter painter(this);
        painter.drawPixmap(0,0,m_pixmap);;
        qDebug()<<"end draw";
    }
}


这样就可以写入将屏幕数据显示在窗口上了,注意,这里只是通过原始数据来导入,并不是为了截屏。如果要想截屏方便,那么可以直接用Qt的截屏函数grabWindow来,而不用Win32的函数!

最后说明一下ARGB数据的具体格式,即是如何排列的,如果颜色用32位表示,那么格式如下:

在本人的电脑上测试,通过截屏获得屏幕数据,biBitCount为32,其ARGB的排列规则见下图:



也可以从DirectX宏函数分析得到:

#define D3DCOLOR_ARGB(a,r,g,b)                  \

                        ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff)))


  • 2
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值