StretchDIBits仅在特定图像维度失败

StretchDIBits failing only at specific image dimensions

本文关键字:失败 图像 StretchDIBits      更新时间:2023-10-16

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

图像数据以24位BGR格式从一些其他图像源加载到无符号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将导致崩溃,因为它试图读取超过缓冲区的末尾。即便如此,我也不知道如何准确诊断它为什么会这样做,因为它在某些尺寸下有效,但在其他尺寸下无效。

您的宽度是错误的字节数。Windows要求每一行都是4个字节的倍数;638*3是1914,少了2个字节。