繁体   English   中英

Win32从设备上下文到文件和/或BLOB创建位图

[英]Win32 Create Bitmap from Device Context To File and/or BLOB

我想将窗口的上下文放入位图。 我使用窗口通过触摸绘制基本线条。 我遇到的问题是我的位图是黑色的。 可能是由于我没有正确获取设备上下文或做其他错误。

函数CreateBitmapInfoStructCreateBMPFile来自此MSDN示例

还要注意, g_hWnd是一个全局变量,具有要为其保存图片的窗口的句柄。

我的最终目标是能够将位图保存到我拥有的mysql字段(BLOB)中。 这就是我最初的问题。 无论如何,我首先尝试创建一个BMP文件。

我在这里和其他地方搜索过。 此MSDN示例之后,这里推荐了我发现的最佳解决方案。 但是,它不起作用。

对于这个特定问题和/或将位图写入blob到mysql表中的任何帮助,将不胜感激。

这是我的代码:

HDC hDC = GetDC(g_hWnd); 

LPRECT rect = (LPRECT)malloc(sizeof(RECT)); 
GetWindowRect(g_hWnd,rect); 
int h = rect->right - rect->left;
int w = rect->bottom - rect->top; 
LPRECT rect = (LPRECT)malloc(sizeof(RECT)); 
GetWindowRect(g_hWnd,rect); 
HBITMAP hBmp = CreateCompatibleBitmap(hDC,w,h); 
PBITMAPINFO pbmi;
pbmi = CreateBitmapInfoStruct(g_hWnd,hBmp); 

CreateBMPFile(g_hWnd, TEXT("c:\\TEMPO\\TestG2.bmp"), pbmi, 
              hBmp, hDC) ;

ReleaseDC(g_hWnd,hDC); 

DeleteObject(hBmp); 
DeleteObject(pbmi); 
if (rect != nullptr)
    free(rect); 

编辑:

捕获屏幕(getDC)的实际答案是在MSDN中修改此样本

我在这里修改了示例(删除了拉伸)请注意,仍然使用goto,我将删除它。
关于GOTO的说明...虽然我不使用它,但我也不认为这是一个问题。 我认为关于GOTO语句的内容太多了...就像在汇编中一样,我们不会执行goto(JUMPS)

这是代码:

void saveBitmap()
{
    HDC hdcScreen;
    HDC hdcWindow;
    HDC hdcMemDC = NULL;
    HBITMAP hbmScreen = NULL;
    BITMAP bmpScreen;

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

    // Create a compatible DC which is used in a BitBlt from the window DC
    hdcMemDC = CreateCompatibleDC(hdcWindow); 
    if(!hdcMemDC)
    {
    goto done;
    }
    RECT rcClient;
    GetClientRect(g_hWnd, &rcClient);
    hbmScreen = CreateCompatibleBitmap(hdcWindow, rcClient.right-rcClient.left, 
                                       rcClient.bottom-rcClient.top);
    if(!hbmScreen)
    {
        goto done;
    }

    SelectObject(hdcMemDC,hbmScreen);

    if(!BitBlt(hdcMemDC, 
               0,0, 
               rcClient.right-rcClient.left, rcClient.bottom-rcClient.top, 
               hdcWindow, 
               0,0,
               SRCCOPY))
    {
        goto done;
    }
GetObject(hbmScreen,sizeof(BITMAP),&bmpScreen);

    BITMAPFILEHEADER   bmfHeader;    
    BITMAPINFOHEADER   bi;

    bi.biSize = sizeof(BITMAPINFOHEADER);    
    bi.biWidth = bmpScreen.bmWidth;    
    bi.biHeight = bmpScreen.bmHeight;  
    bi.biPlanes = 1;    
    bi.biBitCount = 32;    
    bi.biCompression = BI_RGB;    
    bi.biSizeImage = 0;  
    bi.biXPelsPerMeter = 0;    
    bi.biYPelsPerMeter = 0;    
    bi.biClrUsed = 0;    
    bi.biClrImportant = 0;

    DWORD dwBmpSize = ((bmpScreen.bmWidth * bi.biBitCount + 31) / 32) * 4 * 
                      bmpScreen.bmHeight;

    // Starting with 32-bit Windows, GlobalAlloc and LocalAlloc are implemented as wrapper functions that 
    // call HeapAlloc using a handle to the process's default heap. Therefore, GlobalAlloc and LocalAlloc 
    // have greater overhead than HeapAlloc.
    HANDLE hDIB = GlobalAlloc(GHND,dwBmpSize); 
    char *lpbitmap = (char *)GlobalLock(hDIB);    

    // Gets the "bits" from the bitmap and copies them into a buffer 
    // which is pointed to by lpbitmap.
    GetDIBits(hdcWindow, hbmScreen, 0,
              (UINT)bmpScreen.bmHeight,
              lpbitmap,
              (BITMAPINFO *)&bi, DIB_RGB_COLORS);

    // A file is created, this is where we will save the screen capture.
    HANDLE hFile = CreateFile(L"c:\\tempo\\captureqwsx.bmp",
                              GENERIC_WRITE,
                              0,
                              NULL,
                              CREATE_ALWAYS,
                              FILE_ATTRIBUTE_NORMAL, NULL);   

    // Add the size of the headers to the size of the bitmap to get the total file size
    DWORD dwSizeofDIB = dwBmpSize + sizeof(BITMAPFILEHEADER) + 
                        sizeof(BITMAPINFOHEADER);

    //Offset to where the actual bitmap bits start.
    bmfHeader.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + 
                          (DWORD)sizeof(BITMAPINFOHEADER); 

    //Size of the file
    bmfHeader.bfSize = dwSizeofDIB; 

    //bfType must always be BM for Bitmaps
    bmfHeader.bfType = 0x4D42; //BM   

    DWORD dwBytesWritten = 0;
    WriteFile(hFile, (LPSTR)&bmfHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten,  NULL);
    WriteFile(hFile, (LPSTR)&bi, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL);
    WriteFile(hFile, (LPSTR)lpbitmap, dwBmpSize, &dwBytesWritten, NULL);

    //Unlock and Free the DIB from the heap
    GlobalUnlock(hDIB);    
    GlobalFree(hDIB);

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

    //Clean up
done:
    DeleteObject(hbmScreen);
    DeleteObject(hdcMemDC);
    ReleaseDC(NULL,hdcScreen);
    ReleaseDC(g_hWnd,hdcWindow);
}

您可以使用GetDIBits ()。 此功能将图像像素数据复制到您自己分配的内存中。

有关更多详细信息和说明请参见GetDIBits并使用X,Y遍历像素

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM