GDI中控制图的单元测试

时间:2011-01-27 22:49:05

标签: unit-testing winapi drawing gdi

我有一个使用WinAPI用C ++编写的控件,我想自动测试它是否正确绘制。我可以将绘制的图像与保存的参考图像进行比较,或者只是测试特定像素是否具有特定的颜色。我实现了两种类型。

问题是现在测试现在每天都在虚拟机上运行,​​因为某些原因它只有16位颜色深度。这会导致颜色稍微偏离。我试图提出在16位颜色深度绘制时不会改变的颜色,但是舍入方案似乎相当复杂,我需要测试在32b和16b颜色深度都能正常工作。

另一个想法是创建一个总是具有32b颜色深度的屏幕外位图。它的好处是测试每次都会使用相同的环境,但我无法让它工作。无论屏幕颜色深度如何,我如何创建32b HBITMAP和HDC?或者您有任何其他提示如何解决一般问题?

由于

5 个答案:

答案 0 :(得分:1)

我已经通过绘制WMF(现在是EMF)文件完成了GDI单元测试。它确实复制了源(和后来的目标)设备的分辨率和DPI,但我不记得颜色深度是否是“粘性”属性。即使是这样,由于fileformat允许您捕获/重放GDI序列,因此最终可能会有更准确的单元测试。我们将解释WMF文件,以确保我们生成了我们认为应该的东西。

CreateEnhMetaFile是一个起点。

答案 1 :(得分:1)

  

如何创建32b HBITMAP和HDC   无论屏幕颜色深浅?

很简单:

BITMAPINFO bmp_info = {};
bmp_info.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmp_info.bmiHeader.biWidth = width;
bmp_info.bmiHeader.biHeight = height;
bmp_info.bmiHeader.biPlanes = 1;
bmp_info.bmiHeader.biBitCount = 32;
bmp_info.bmiHeader.biCompression = BI_RGB;

HDC mem_dc = CreateCompatibleDC(0);
void *dummy;
HBITMAP bitmap_handle = CreateDIBSection(mem_dc, &bmp_info, DIB_RGB_COLORS, &dummy, NULL, 0);
SelectObject(mem_dc, bitmap_handle));

现在在此DC上绘制按钮。请记住检查错误并释放资源。

或者,自动将按钮参考视图转换为实际的桌面模式:

HWND desktop = GetDesktopWindow();
HDC desktop_dc = GetDC(desktop);
HDC mem_dc = CreateCompatibleDC(desktop_dc); 
RECT rect;
GetClientRect(desktop, &rect);
HBITMAP bitmap_handle = CreateCompatibleBitmap(desktop_dc, rect.right - rect.left, rect.bottom - rect.top);
SelectObject(mem_dc, bitmap_handle);

现在BitBlt预加载的图像超过mem_dc。它将自动转换为当前桌面颜色模式

答案 2 :(得分:1)

如何使用GDI +创建屏幕外位图,然后使用GDI绘制它 - 如下所示:

int width=64; // or whatever you need
int height=100;
int stride = width*4;
BYTE buffer[stride*height];
Gdiplus::Bitmap bitmap(width, height, stride, PixelFormat32bppARGB, buffer);
Gdiplus::Graphics g (&bitmap);
HDC dc = g.GetHDC();

// drawing code, using WinAPI, to draw to dc

g.ReleaseHDC();

// Now compare the contents of your buffer

有关gdi / gdi + interop的更多信息,请访问:http://support.microsoft.com/kb/311221

答案 3 :(得分:0)

如您所说,创建一个32bpp的屏幕外表面,或者使用比较参考图像执行完全相同的操作,这样您就可以在同一个bpp上测试它们。换句话说,不要做自己的舍入;让GDI系统对两个表面进行相同的舍入。

答案 4 :(得分:0)

如果与32位图像或16位图像进行比较,则将测试更改为通过。捕获32位版本和16位版本(运行虚拟)。这非常快速且易于实施。

您应该已经有了一种自动方法来捕获已知良好版本代码的参考图像。如果不这样做,请立即执行此操作,因为当您对控件的外观进行微小更改时,可以节省您的时间。您现在有了回归测试的参考。