点击打开链接
函数原型:
- 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((const uchar*)byteArray.data(),byteArray.size());
- 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)))