• 전체강좌

    BMP 파일에서 RGB 데이터 읽어오기

    twitter facebook

    안녕하세요? 착한이입니다.

     

    이미지 파일에는 여러 종류가 있습니다.

     

    잘 알고 있는 bmp, jpg, png, tga, gif 등이 있습니다.

     

    압축되지 않은 RGB 데이터를 저장하고 있는 bmp 파일과 tga 파일의 경우, 영상 처리 또는 OpenGL ES에서 Texture로 만들기 위한

     

    이미지 파일을 로딩할 때, 많이 사용됩니다.

     

    이 중에서 bmp 파일에서 RGB 데이터를 얻는 방법에 대해 알아 보겠습니다.

     

    bmp 파일은 헤더 부분과 실제 RGB 데이터로 이루어져 있습니다. 헤더 부분에는 이미지 파일의 크기, 포멧 등의 데이터가

     

    포함되어 있습니다. 구조는 간단하지만 모두 다 알고 계실 필요는 없습니다. ^^

     

    간단히 함수로 만들어 두면 다음에는 이를 이용하시면 되니 편하겠죠? ^^

     

    그리고 RGB 데이터를 저장할 때에는 BMP 파일의 경우 이미지가 거꾸로 들어가 있다는 것을 주의 해 주세요.

     

    당연히 뒤집어 주어야 합니다.  아래 코드에서는 생략 되어 있습니다.

     

    // BMP 파일에서 RGB 데이터를 로딩한다. 동시에 크기도 얻어온다. 24bpp or 32bpp BMP 파일 로딩
    int LoadBmpFile(TCHAR *filename, BYTE **pData, int *width, int *height){

     BITMAPFILEHEADER FileHeader;
     BITMAPINFOHEADER InfoHeader;
     RGBQUAD* Palette;
     HANDLE BitmapFile;
     DWORD BitmapLength;
     DWORD PaletteLength;
     DWORD ReadBytes;

     *width=0;
     *height=0;

     

     BitmapFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0);
     if (BitmapFile == INVALID_HANDLE_VALUE)
     {
             return 0;
     }

     //  Header data를 읽는다.
     ReadFile(BitmapFile, &FileHeader, sizeof(FileHeader), &ReadBytes, NULL);
     ReadFile(BitmapFile, &InfoHeader, sizeof(InfoHeader), &ReadBytes, NULL);

     

     // palette 처리
     PaletteLength = InfoHeader.biClrUsed;

     if(PaletteLength>0){

              Palette = new RGBQUAD[PaletteLength];
              ReadFile(BitmapFile, Palette, PaletteLength, &ReadBytes, NULL);
              if (ReadBytes != PaletteLength)
             {
                        if(Palette!=NULL) delete Palette;
                         return 0;
              }
     }
     else{

             Palette=NULL;
     }

     

     *width = InfoHeader.biWidth; // 넓이 저장
     *height = InfoHeader.biHeight; //높이 저장

     

    BitmapLength = InfoHeader.biSizeImage;
     if (BitmapLength == 0)
            BitmapLength = InfoHeader.biWidth* InfoHeader.biHeight * InfoHeader.biBitCount / 8;

     

    // 저장할 공간을 할당
     *pData= new BYTE[BitmapLength];
     BYTE *pRGBBuf=*pData;
     ReadFile(BitmapFile, pRGBBuf, BitmapLength, &ReadBytes, NULL);
     if (ReadBytes != BitmapLength)
     {
              delete *pData;
              if(Palette!=NULL) delete Palette;
              return 0;
     }
     CloseHandle(BitmapFile);

               if(Palette!=NULL) delete Palette;
               return 1;

    }

     

    내용 보시면 참 간단하죠? 하나 중요한 것은 RGB 데이터를 저장하는 공간이 동적으로 할당되므로 사용후에는 삭제 해 주어야 합

     

    니다.

     

    이미지 파일들을 다를 수 있는 API 들이 제공되고 있지만 간단히 테스트할 때는 직접 구현해 보는 것도 좋을 듯 합니다.

    그럼 즐거운 개발 하세요.