Модульное тестирование контрольного чертежа в GDI - PullRequest
2 голосов
/ 28 января 2011

У меня есть элемент управления, написанный на C ++ с использованием WinAPI, и я хотел бы автоматически проверить правильность его прорисовки.Я могу либо сравнить нарисованное изображение с сохраненными эталонными изображениями, либо просто проверить, имеют ли определенные пиксели определенный цвет.У меня реализованы оба типа.

Проблема в том, что тесты теперь также проводятся каждую ночь на виртуальной машине, которая по какой-то причине имеет только 16-битную глубину цвета.Это приводит к тому, что цвета немного смещены.Я пытался придумать цвета, которые не изменились бы при рисовании с глубиной цвета 16 бит, но схема округления кажется довольно сложной, и мне нужно, чтобы тесты работали как на 32b, так и на 16b глубины цвета.1004 * Другая идея заключалась в создании закадрового растрового изображения, которое всегда имело бы глубину цвета 32 бита.Было бы полезно, чтобы тесты каждый раз использовали одну и ту же среду, но я не мог заставить это работать.Как я могу создать 32b HBITMAP и HDC независимо от глубины цвета экрана?Или у вас есть другие советы, как решить общую проблему?

Спасибо

Ответы [ 5 ]

1 голос
/ 12 февраля 2011

Как насчет использования 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

1 голос
/ 11 февраля 2011

Как я могу создать 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. Он будет автоматически преобразован в текущий цветовой режим рабочего стола

1 голос
/ 28 января 2011

Я провел модульное тестирование GDI, нарисовав файл WMF (теперь EMF).Он действительно копировал разрешение и DPI устройства источника (и более позднего назначения), но я не помню, был ли цветовой признак «липким» атрибутом.Даже если бы это было так, поскольку файловый формат позволяет вам захватывать / воспроизводить последовательность GDI, в любом случае у вас может быть более точный модульный тест в конце.Мы интерпретируем файл WMF, чтобы убедиться, что мы сгенерировали то, что, как мы думали, должны.

CreateEnhMetaFile является отправной точкой.

0 голосов
/ 12 февраля 2011

Измените свой тест на прохождение, если сравнение с 32-битным изображением или с 16-битным изображением в порядке. Захват 32-битных и 16-битных версий (работает виртуальный). Это действительно быстро и легко реализовать.

У вас уже должен быть автоматический способ захвата эталонных изображений для известной хорошей версии кода. Если вы этого не сделаете, сделайте это сейчас, так как это сэкономит ваше время позже, когда вы внесете небольшие изменения в внешний вид элемента управления. Теперь у вас есть ссылка для регрессионного тестирования.

0 голосов
/ 10 февраля 2011

Либо создайте 32-битную экранную поверхность, как вы сказали, либо выполните точно такую ​​же операцию со своим сравнительным эталонным изображением, чтобы вы тестировали оба на одном bpp.Другими словами, не делайте свое собственное округление;пусть система GDI выполняет одинаковое округление до обеих поверхностей.

...