在32位和64位进程中,GDI位图/ DC的像素大小限制是多少?

时间:2016-12-27 06:54:38

标签: c++ windows winapi bitmap gdi

我编写了一个执行低级打印的Win32应用程序,我正在处理GDI bitmaps and device contexts

代码基本上这样做(伪代码):

HDC hCompDc = ::CreateCompatibleDC(hDC);

BITMAPINFOHEADER infoHeader = {0};

infoHeader.biSize          = sizeof(infoHeader);
infoHeader.biWidth         = nWidth;
infoHeader.biHeight        = -nHeight;      //The document must be right side up
infoHeader.biPlanes        = 1;
infoHeader.biBitCount      = 24;
infoHeader.biCompression   = BI_RGB;

BITMAPINFO info;
info.bmiHeader = infoHeader;

//Use file on disk to store large bitmap data
HANDLE hFileScatch = ::CreateFile(strTempPath, 
    GENERIC_READ | GENERIC_WRITE, 0, NULL, 
    CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

UINT64 ncbLineSz = nWidth * 3;
if(ncbLineSz & 0x3)
    ncbLineSz = (ncbLineSz & ~0x3) + 0x4;       //Must be DWORD aligned

UINT64 uiSzBmp = ncbLineSz * nHeight;

HANDLE hFileMapObj = ::CreateFileMapping(hFileScatch,
    NULL, PAGE_READWRITE, (DWORD)(uiSzBmp >> 32), (DWORD)(uiSzBmp), NULL);

BYTE* pMemory = 0;
HBITMAP hBitmap = ::CreateDIBSection(hDC, &info, DIB_RGB_COLORS, (void**)&pMemory, hFileMapObj, 0);

::SelectObject(hCompDc, hBitmap);

//Do drawing on `hCompDc` using other GDI APIs
//...

//And print
::SetAbortProc(hPrintDC, _printerAbortProc);
::StartDoc(hPrintDC, &docInfo);
::StartPage(hPrintDC);

::BitBlt(hPrintDC, 
    rcPrintArea.left,
    rcPrintArea.top, 
    rcRenderArea.Width(), 
    rcRenderArea.Height(), 
    hCompDc,                    //DC from
    rcRenderArea.left,
    rcRenderArea.top,
    SRCCOPY);

::EndPage(hPrintDC);

//Clean up, etc.
//...

这在某种程度上有效。让我解释一下:

由于我处理的打印机分辨率为300 dpi(而普通屏幕为96 dpi),因此位图的大小非常大。

例如,如果我的位图为3900 x 86625像素,则需要大约966 MB的DIB部分。 (我可以了解到,如果我在上面的代码中CreateDIBSection替换默认内存分配,并使用file mapping object支持file on disk。)否则,我知道我可以达到连续的限制具有该块内存的32位进程中的RAM空间。但事实并非如此。

当我在32位进程中运行具有该位图大小的代码时,使用由file mapping object支持的file on disk创建位图,但生成的位图/图像完全显示空白,而在64位进程中编译的完全相同的代码,会产生一个看起来很正常的位图。

因此,鉴于GDI对象存在特定的图像大小限制,我很好奇吗?对于32位和64位进程。

还有一个附带问题 - 是否有任何方法可以知道在绘制时达到了这样的尺寸限制?

PS。我的实际代码对所有Win32 API都进行了所有错误检查,虽然我上面描述的32位进程产生了一个空白位图,但它在单个GDI API中没有失败。

0 个答案:

没有答案