• 전체강좌

    BMP(RGB)를 hex header 로 변환하기

    twitter facebook

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

    Eboot 와 같이 부트에서 부팅화면을 변경하려면

    BMP 파일을 바로 사용할 수 없습니다. 배열로 잡아서 처리하면 되지만 일반적으로 header 를 제거하고

    hex 형태의 text  형태로 변경해서 사용하게 됩니다.

    아래 소스 코드는 24bpp 또는 32bpp BMP 파일을 hex header 파일로 변환해 주는 코드 입니다.

    생성되는 헤더파일을 eboot 에 추가하시면 부팅 화면을 변경 가능합니다.

    그럼 유용하게 사용하세요. ^^ 


    // BMP2Hex.cpp : Defines the entry point for the console application.
    //

    #include "stdafx.h"
    #include <windows.h>


    int _tmain(int argc, _TCHAR* argv[])
    {
     TCHAR *bmpfilename=L"d:\\Test.bmp"; // BMP 파일 명
     TCHAR *hexfilename=L"d:\\Test.h"; // 출력 hex header 파일 명


      BITMAPFILEHEADER FileHeader; // BMP 구조체
      BITMAPINFOHEADER InfoHeader;
      RGBQUAD* Palette;
      HANDLE BitmapFile;
      DWORD BitmapLength;
      DWORD PaletteLength;
      DWORD ReadBytes;

     

     // BMP 파일 열기

      BitmapFile = CreateFile(bmpfilename, 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;
      }

     
      // RGB 크기를 구한다.

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

     

     // 저장할 공간을 할당
      BYTE *pData= new BYTE[BitmapLength];
      BYTE *pRGBBuf=pData;
      ReadFile(BitmapFile, pRGBBuf, BitmapLength, &ReadBytes, NULL); //RGB 데이터를 읽는다.
      if (ReadBytes != BitmapLength)
      {
         delete pData;
         if(Palette!=NULL) delete Palette;
         return 0;
      }
      CloseHandle(BitmapFile);

     if(Palette!=NULL) delete Palette;
        

         //hex header file 생성

     HANDLE hexfile=NULL;
      hexfile = CreateFile(hexfilename, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, 0);
      if (hexfile == INVALID_HANDLE_VALUE)
      {
       delete pData;
        return 0;
      }

     

      TCHAR tmp[200];
      DWORD WriteBytes;
      wcscpy(tmp, L"#ifndef _BMP2HEX_H\n"); // header 파일로 만들기 위한 출력
      WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);
      wcscpy(tmp, L"#define _BMP2HEX_H\n");
      WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);
      wcscpy(tmp, L"const unsigned int HEXBYKMS[] ={ \n");
      WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);

      int count =0;
      BYTE *pSrc=pData;
      unsigned int rgbdata;

      int add=InfoHeader.biBitCount/8;

     

      for(int i=0; i<InfoHeader.biHeight; i++){ // BMP 파일에는 이미지가 거꾸로 들어가 있으므로 뒤집기
        pSrc=pData + (InfoHeader.biHeight-1 -i)*InfoHeader.biWidth*add; // 뒤집기
        for(int j=0; j<InfoHeader.biWidth; j++){

         if(add==3){
          rgbdata=pSrc[2]<<16 | pSrc[1]<<8 | pSrc[0];
         }
         else if(add==4){
          rgbdata=pSrc[3]<<24 | pSrc[2]<<16 | pSrc[1]<<8 | pSrc[0];
         }
         count++;
         pSrc+=add;

      
         wsprintf(tmp, L"0x%08X, ", rgbdata); // hex 형태로 출력한다.
         WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);
         if(count%10 ==0){
          wcscpy(tmp, L"\n");
          WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);
         }

        }
      } 

      wcscpy(tmp, L"};\n");
      WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);
      wcscpy(tmp, L"#endif\n");
      WriteFile(hexfile, tmp, wcslen(tmp)*sizeof(TCHAR), &WriteBytes, NULL);
      CloseHandle(hexfile);

      delete pData;


      return 1;
    }