Здравствуйте коллеги!
Помогите пожалуйста разобраться с загрузкой BITMAP изображения.
Изображение не рисуется.
Код:
void __fastcall TForm1::btnNewLoadClick(TObject *Sender)
{
int w, h;
long size;
HDC hMemDC = CreateCompatibleDC(Image1->Canvas->Handle);
HBITMAP hBMP = (HBITMAP)LoadBMP(&w, &h, &size, "fnew.bmp", hMemDC);
BITMAP bmp;
//ОШИБКА ПРОЯВЛЯЕТСЯ УЖЕ ЗДЕСЬ. ИНИЦИАЛИЗАЦИЯ bmp НЕ ПРОИСХОДИТ!
if(GetObject(hBMP, sizeof(BITMAP), &bmp) == NULL)
{
MessageBox(NULL, "Error, GetObject(hBMP)", "ERROR", MB_OK);
DeleteDC(hMemDC);
DeleteObject(hBitmap);
return;
}
if(SelectObject(hMemDC, hBMP) == NULL)
msger();
if(BitBlt(Image1->Canvas->Handle,
0,
0,
bm.bmWidth,
bm.bmHeight,
hMemDC,
0,
0,
SRCCOPY) == NULL)
msger();
DeleteDC (hMemDC);
DeleteObject(hBMP);
}
Не обращайте внимания на SizeBITMAPFILEHEADER, с этим все в порядке.
Все хедеры читаются корректно, массив BGR кажется тоже(ошибок хотя бы не разу не возникало). Далее переворачиваются данные, думал ошибка в алгоритме, но пробовал и другие вариации, ничего не изменилось.
Код:
BYTE* TForm1::LoadBMP(int* width, int* height, long* size, LPCTSTR bmpfile, HDC dc)
{
BITMAPFILEHEADER bmpheader;
BITMAPINFOHEADER bmpinfo;
DWORD bytesread;
HANDLE file = CreateFile ( bmpfile , GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
if ( NULL == file )
return NULL; // coudn't open file
int SizeBITMAPFILEHEADER = sizeof(bmpheader.bfType) + sizeof(bmpheader.bfSize) + sizeof(bmpheader.bfReserved1) + sizeof(bmpheader.bfReserved2) + sizeof(bmpheader.bfOffBits);
if(sizeof(BITMAPFILEHEADER) != 16 && sizeof(BITMAPFILEHEADER) != 14)
SizeBITMAPFILEHEADER = sizeof(BITMAPFILEHEADER);
if(SizeBITMAPFILEHEADER == sizeof(BITMAPFILEHEADER))
{
if(ReadFile(file, &bmpheader, SizeBITMAPFILEHEADER, &bytesread, NULL) == NULL)
{
CloseHandle(file);
return NULL;
}
}
else
{
ReadFile(file, &bmpheader.bfType, sizeof(bmpheader.bfType), &bytesread, NULL);
ReadFile(file, &bmpheader.bfSize, sizeof(bmpheader.bfSize), &bytesread, NULL);
ReadFile(file, &bmpheader.bfReserved1, sizeof(bmpheader.bfReserved1), &bytesread, NULL);
ReadFile(file, &bmpheader.bfReserved2, sizeof(bmpheader.bfReserved2), &bytesread, NULL);
ReadFile(file, &bmpheader.bfOffBits, sizeof(bmpheader.bfOffBits ), &bytesread, NULL);
}
if ( ReadFile ( file, &bmpinfo, sizeof ( BITMAPINFOHEADER ), &bytesread, NULL ) == false )
{
CloseHandle ( file );
return NULL;
}
if ( bmpheader.bfType != 'MB' )
{
CloseHandle ( file );
return NULL;
}
*width = bmpinfo.biWidth;
*height = abs ( bmpinfo.biHeight );
if ( bmpinfo.biCompression != BI_RGB )
{
CloseHandle ( file );
return NULL;
}
if ( bmpinfo.biBitCount != 24 )
{
CloseHandle ( file );
return NULL;
}
*size = bmpheader.bfSize - bmpheader.bfOffBits;
BYTE* Buffer = new BYTE[ *size ];
if(SetFilePointer ( file, bmpheader.bfOffBits, NULL, FILE_BEGIN ) == 0xFFFFFFFF)
{
msger();
}
ReadFile ( file, Buffer, *size, &bytesread, NULL);
if(bytesread == 0)
{
msger();
delete [] Buffer;
CloseHandle ( file );
return NULL;
}
CloseHandle ( file );
BYTE* RGBBuffer = ConvertBMPToRGBBuffer (Buffer, *width, *height);
delete [] Buffer;
return RGBBuffer;
}
Код:
BYTE* TForm1::ConvertBMPToRGBBuffer ( BYTE* Buffer, int width, int height )
{
if ( ( NULL == Buffer ) || ( width == 0 ) || ( height == 0 ) )
return NULL;
// find the number of padding bytes
int padding = 0;
int scanlinebytes = width * 3;
while ( ( scanlinebytes + padding ) % 4 != 0 ) // DWORD = 4 bytes
padding++;
// get the padded scanline width
int psw = scanlinebytes + padding;
// create new buffer
BYTE* newbuf = new BYTE[width*height*3];
// now we loop trough all bytes of the original buffer,
// swap the R and B bytes and the scanlines
long bufpos = 0;
long newpos = 0;
for ( int y = 0; y < height; y++ )
for ( int x = 0; x < 3 * width; x+=3 )
{
newpos = y * 3 * width + x;
bufpos = ( height - y - 1 ) * psw + x;
newbuf[newpos] = Buffer[bufpos + 2];
newbuf[newpos + 1] = Buffer[bufpos+1];
newbuf[newpos + 2] = Buffer[bufpos];
}
return newbuf;
}