Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 09.11.2014, 16:54   #1
st_yak
Пользователь
 
Регистрация: 20.07.2013
Сообщений: 18
Сообщение Загрузка изображения BITMAP из файла.

Здравствуйте коллеги!
Помогите пожалуйста разобраться с загрузкой 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;
}
st_yak вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Сохранение изображения из DrawingArea в Bitmap Mixim C# (си шарп) 2 12.12.2012 11:33
Как загрузить изображения с использованием Bitmap Pilgrimm C++ Builder 2 24.03.2011 07:56
Загрузка картинки в BitMap Gerzs Мультимедиа в Delphi 18 04.10.2010 19:45
Загрузка BitMap из DLL Македонский Мультимедиа в Delphi 2 02.06.2009 17:28