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

时间:2012-12-05 01:25:57

标签: 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);

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

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

1 个答案:

答案 0 :(得分:5)

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