2015-08-28 3 views
0

Просто, чтобы узнать Windows API, я пытаюсь использовать дешевое устройство отпечатков пальцев, которое я купил. Библиотека, которая пришла с ней, захватывает отпечаток пальца как 8-битную растровую карту размером 256x280 пикселей и сохраняет исходные пиксели в буфере.Цвета не отображаются правильно

Я пытаюсь скопировать этот поток необработанного пикселя в независимый от устройства битмап (DIB), а затем попытаться использовать этот DIB для рисования на окне.

Мне удалось отобразить изображение, но все цвета были неправильными. Heres часть кода, которая обрабатывает картину.

PAINTSTRUCT ps; 
HDC hdc,memDC; 

HBITMAP cp_bmp; 

HBITMAP di_bmp; 
BITMAPINFO di_bmp_info; 
void *di_bmp_data; 

int ptr; 
int x,y; 

int aux; 

ZeroMemory(&di_bmp_info,sizeof(BITMAPINFO)); 
di_bmp_info.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 
di_bmp_info.bmiHeader.biWidth=256; 
di_bmp_info.bmiHeader.biHeight=280; 
di_bmp_info.bmiHeader.biPlanes=1; 
di_bmp_info.bmiHeader.biBitCount=8; 
di_bmp_info.bmiHeader.biCompression=BI_RGB; 

hdc=BeginPaint(hwnd,&ps); 

// create the DIB 
di_bmp=CreateDIBSection(hdc,&di_bmp_info,DIB_RGB_COLORS,&di_bmp_data,NULL,0); 

// Copy the original bitstream onto the DIB 
CopyMemory(di_bmp_data,fingerprint,256*280); 

// create the mem dc 
memDC=CreateCompatibleDC(hdc); 

// create the DDB 
cp_bmp=CreateCompatibleBitmap(hdc,256,280); 
SelectObject(memDC,cp_bmp); 

SetDIBits(memDC,cp_bmp,0,280,di_bmp_data,&di_bmp_info,DIB_RGB_COLORS); 
BitBlt(hdc,10,10,256,280,memDC,0,0,SRCCOPY); 
DeleteObject(cp_bmp); 
EndPaint(hwnd,&ps); 

Любопытный факт, что при изменении di_bmp_info.bmiHeader.biBitCount на 32, дисплей цветов отлично, но изображение становится меньше по размеру и получает повторяется около 5 или шесть раз по горизонтали.

Я застрял !. Заранее спасибо.

+0

У вас есть более конкретная информация о формате пиксельных данных, которые вы получаете от считывателя отпечатков пальцев? Например, можете ли вы предоставить шестнадцатеричный дамп первой строки пикселей? Также совместимое растровое изображение не нужно, если вы просто рисуете DIB в окне DC; вы можете выбрать независимый от устройства HBITMAP в совместимый DC, и он должен работать отлично. – andlabs

ответ

4

Короче говоря, у вас есть индексированное растровое изображение (каждый пиксель не является значением RGB, а вместо него индексом в определенной палитре цветов), и вы не предоставили палитру для его использования.

BITMAPINFO - это структура с переменным размером - BITMAPINFOHEADER, за которой следует, по меньшей мере, одно, но потенциально более RGBQUAD структур. Для индексированных глубин растровых изображений (8 бит/с и ниже) палитру необходимо предоставить после BITMAPINFOHEADER в памяти.

Количество требуемых элементов палитры определяется полями biBitCount и biClrUsed. Если biClrUsed равно 0, количество записей палитры должно быть 1 << biBitCount или 256 в случае 8bpp. Установка biClrUsed на что-то, кроме 0, позволяет вам предоставить меньше записей палитры, если битмап им не нужен.

Поскольку вы не установили biClrUsed, предполагается, что полная цветовая палитра 256 будет соответствовать памяти BITMAPINFOHEADER и в основном используется случайная память.

BITMAPINFO обеспечивает только один RGBQUAD себя так, что вам нужно расширить структуру, чтобы обеспечить остальное, например:

struct MyBitmapInfo 
{ 
    BITMAPINFOHEADER bmiHeader; 
    RGBQUAD palette[256]; 
}; 

Где вы на самом деле получить палитру от до вас, но вы могли бы, например, используйте палитру оттенков серого:

struct MyBitmapInfo di_bmp_info; 

ZeroMemory(&di_bmp_info,sizeof(struct MyBitmapInfo)); 
di_bmp_info.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); 
di_bmp_info.bmiHeader.biWidth=256; 
di_bmp_info.bmiHeader.biHeight=280; 
di_bmp_info.bmiHeader.biPlanes=1; 
di_bmp_info.bmiHeader.biBitCount=8; 
di_bmp_info.bmiHeader.biCompression=BI_RGB; 

// initialise greyscale palette 
for (int i = 0; i < 256; i++) 
{ 
    di_bmp_info.palette[i].rgbRed = 
    di_bmp_info.palette[i].rgbGreen = 
    di_bmp_info.palette[i].rgnBlue = i; 
} 
Смежные вопросы