StretchDIBits仅在特定图像尺寸下失败

Jus*_*n G 1 c++ windows crash gdi stretchdibits

我正在使用StretchDIBits打印图像,当图像由于某种未知原因而处于特定大小时,它会失败.

图像数据从24位BGR格式的某些其他图像源加载到unsigned int数组中.我已经验证了图像和缓冲区完全没问题,因为就像我说的那样,它可以在某些尺寸上工作但根本不工作.

我正在测试的当前尺寸是638x1014.如果我将高度更改为1013它可以正常工作,但由于某种原因,如果它是1014,它就会失败.

这里有一些代码向您展示如何设置它们:

unsigned int * buffer = new unsigned int[width * height * 3];

// Fill buffer with image data...

BITMAPINFOHEADER bi = { 0 };
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = width;
bi.biHeight = height;
bi.biPlanes = 1;
bi.biBitCount = 24;
bi.biCompression = BI_RGB;
bi.biSizeImage = width * height * 3; // Specifying this value because if I don't it will crash trying to read outside of the buffer.

StartPage(hdcPrint);
SetMapMode(hdcPrint, MM_ISOTROPIC);
SetWindowExtEx(hdcPrint, width, height, NULL);
SetViewportExtEx(hdcPrint, width, height, NULL);
SetViewportOrgEx(hdcPrint, 0, 0, NULL);

StretchDIBits(hdcPrint, 0, 0, width, width, 0, 0, width, height, buffer, (BITMAPINFO *) &bi, DIB_RGB_COLORS, SRCCOPY);
Run Code Online (Sandbox Code Playgroud)

StretchDIBits 失败时返回零,打印结果为空白页.

我对问题的含义有一个模糊的概念,因为就像在评论中所说的那样,如果我没有指定biSizeImage并将其保留为零,StretchDIBits则会导致崩溃,因为它试图读取超过缓冲区的末尾.即便如此,我也不知道如何确切地诊断它为什么这样做,因为它适用于某些尺寸而不是其他尺寸.

Mar*_*som 5

您的宽度是错误的字节数.Windows要求每行是4个字节的倍数; 638*3是1914年,这是2个字节害羞.