读取位图并显示对话框上的范围

时间:2011-11-02 21:30:04

标签: visual-c++

问题:无法将图像传到屏幕上...... 我正在寻找一种方法,我可以使用相机和一个文件,我可以使用GetDIBits和SetDIBits修改位图并写入屏幕。

目前为止从文件到屏幕......无法正常工作

HDC hdcScreen;
HDC hdcWindow;
HDC hdcMemDC = NULL;
HBITMAP hbmScreen = NULL;
BITMAP bmpScreen;

BITMAPFILEHEADER   bmfHeader;    
BITMAPINFOHEADER   bi;
BITMAPINFO bif;




// Retrieve the handle to a display device context for the client 
// area of the window. 
hdcScreen = ::GetDC(NULL);
// hdcWindow = ::GetDC(hWndC);

// Create a compatible DC which is used in a BitBlt from the window DC
hdcMemDC = CreateCompatibleDC(hdcWindow); 

HANDLE hFile = ::CreateFile("c:\\captureqwsx.bmp",
    GENERIC_READ,
    0,
    NULL,
    OPEN_ALWAYS,
    FILE_ATTRIBUTE_NORMAL, NULL);   


DWORD nBytesRead = 0;
ReadFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &nBytesRead, NULL);
ReadFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &nBytesRead, NULL);
//HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); 
char *lpbitmap;// = (char *)GlobalLock(hDIB); 
DWORD dwBmpSize;// = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * bmpScreen.bmHeight;
ReadFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &nBytesRead, NULL);




//Close the handle for the file that was created
CloseHandle(hFile);



//CRect rect;
//GetClientRect(&rect);

bif.bmiHeader = bi;

HDC hDC = hdcWindow;


HBITMAP hBitmap;
HDC hMemDC;

hBitmap = CreateCompatibleBitmap(hDC, bi.biWidth, bi.biHeight);
hMemDC = CreateCompatibleDC(hDC);
SetDIBits(hDC, hBitmap, 0, bi.biHeight, lpbitmap, &bif, DIB_RGB_COLORS);
SelectObject(hMemDC, hBitmap);
BitBlt(hDC, 0, 0, bi.biWidth, bi.biHeight, hMemDC, 0, 0, SRCCOPY);

DeleteObject(SelectObject(hMemDC, hBitmap));
DeleteDC(hMemDC);

2 个答案:

答案 0 :(得分:1)

        dcMem.DeleteDC();
        hbmScreen = CreateCompatibleBitmap(dc, m_rectFrame2.right-m_rectFrame2.left, m_rectFrame2.bottom-m_rectFrame2.top);// <-- needed
        dcMem.CreateCompatibleDC(&dc);
        hbmScreen = (HBITMAP)LoadImage(NULL, _T("c:\\captureqwsx.bmp") ,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
   //for setDiBits    
    SetDIBits(hdcWindow, hbmScreen, 0,  
                  (UINT)bmpScreen.bmHeight,
                  lpbitmap,  
                  (BITMAPINFO *)&bi, DIB_RGB_COLORS);
        dcMem.SelectObject(hbmScreen);
        dc.StretchBlt( 
                   m_rectFrame2.left, m_rectFrame2.top, 
                   m_rectFrame2.right-m_rectFrame2.left,//GetSystemMetrics (SM_CXSCREEN),
                   m_rectFrame2.bottom-m_rectFrame2.top,//GetSystemMetrics (SM_CYSCREEN),
                   &dcMem, 
                   0,0,
                   m_rectFrame2.right-m_rectFrame2.left,//GetSystemMetrics (SM_CXSCREEN),
                   m_rectFrame2.bottom-m_rectFrame2.top,//GetSystemMetrics (SM_CYSCREEN),
                   SRCCOPY);

答案 1 :(得分:1)

在这里,您可以检索整个屏幕的DC。那是你真正想要的吗?

GetDC(NULL);

也许你应该删除它并取消注释以下行:

// hdcWindow = ::GetDC(hWndC); 

根据发布的示例,您使用未初始化的'hdcWindow'参数调用CreateCompatibleDC()。

hdcMemDC = CreateCompatibleDC(hdcWindow);

在阅读BITMAPFILEHEADER和BITMAPINFOHEADER之后,您应该将文件指针移动到BITMAPFILEHEADER :: bfOffBits offest。 然后你应该调用ReadFile()来读取位图本身。顺便说一下,所需的缓冲区大小在BITMAPINFOHEADER :: biSizeImage中。

由于hdcWindow未初始化,hDC仍然未初始化:

hDC = hdcWindow;

您是否检查过SetDIBits()的返回值?

尝试修改以下行:

hOldBitmap = SelectObject(hMemDC, hBitmap);

然后,在BitBlt()之后:

DeleteObject(SelectObject(hMemDC, hOldBitmap));

我不知道这是否是您问题的最终解决方案,但这是一个开始。

相关问题