본문 바로가기
프로그래밍/MFC

Raw to BMP 저장

by 완소루피 2020. 11. 13.
728x90
반응형

BMP로 저장된 내용을 불러서 BMP로 저장하는 소스는 많이들 보셨을 겁니다. 그런
데 저같은 경우 RAW파일을 저장할려고 하는 부분에서 고생을 좀 했습니다. 특히나 흑백 컬러
에서 RGBQUAD를 체우는 방법을 몰라 많이 많이 고생했는데 혹시나 이 것 때문에 고생 하는 
분이시라면 아래의 코드를 이용하세요 그리고 조금만 공부하면 BMP의 구조는 쉽게 이해하실 
수 있을겁니다.

 

   #define DIB_HEADER_MAKER ((WORD)('M' << 8) | 'B')//BM MARKER
    // TODO: Add your command handler code here
    int width = 1300;//저장하려는 raw이미지 크기데로 설정하세요
    int height = 1030;
    int color = 256;//모노크롬은 256의 Gray level을 갖죠
    DWORD size,len; //파일 헨들링하는데 쓰려구

/*******BitmapInfo를 메모리에 로드합니다.*********************/
    int infosize;
    LPBITMAPINFO pBitmapInfo = NULL;
    if(pBitmapInfo)
        delete pBitmapInfo;
    infosize=sizeof(BITMAPINFO)+(sizeof(RGBQUAD)*color);
    //infosize=sizeof(BITMAPINFO);
    pBitmapInfo =(LPBITMAPINFO) new char[infosize];
/*************************************************************/
    
//Bitmap을 저장하려면 해더가 있어야죠
    BITMAPFILEHEADER bfHeader;
    
// 설명이 없는 부분을 MSDN이나 책을 참조하세요..............
    pBitmapInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);//Size of 
bmiHeader
    pBitmapInfo->bmiHeader.biWidth = width;
    pBitmapInfo->bmiHeader.biHeight = height;
    pBitmapInfo->bmiHeader.biPlanes = 1;
    
    //영상의 DEPTH 256 Color은 8로 설정 합니다.
    pBitmapInfo->bmiHeader.biBitCount = 8;
    //가로 길이 4배수의 나머지 값 얻기
    /*dumy = width%4;
    ((4-dumy)==4)?dumy = 0:dumy = 4-dumy;
    BitmapInfo.bmiHeader.biSizeImage=(width+dumy)*height;*/
//BMP는 가로길이 4배수로 저장해야 되는데 로우 이미지가 4배수라서 아래처럼 했슴당.
    pBitmapInfo->bmiHeader.biSizeImage=width*height;

    pBitmapInfo->bmiHeader.biCompression = BI_RGB;//Whether Compression or 
non compression
    pBitmapInfo->bmiHeader.biXPelsPerMeter = 0; // Meter per XPixel
    pBitmapInfo->bmiHeader.biYPelsPerMeter = 0; // Meter per YPixel
    pBitmapInfo->bmiHeader.biClrUsed = 256; //Real Color If 0 then use 
maximum colors
    pBitmapInfo->bmiHeader.biClrImportant = 0;
// 자 BITMAPINFOHEADER을 설정 했으니 BITMAPHEADER을 설정해볼까요....

    //Coding about BITMAPFILEHEADER
    bfHeader.bfType = DIB_HEADER_MAKER;//'BM'
    bfHeader.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
        +((color)*sizeof(RGBQUAD));//Location of bitmap data
//혹시나 해서 위의 3개 구조체의 크기를넘어서면 그곳에 비트맵 데이타가 저장되죠 그 위치
를 갖습니다.
    bfHeader.bfSize = sizeof(bfHeader)+((color-1)*sizeof(RGBQUAD))
+pBitmapInfo->bmiHeader.biSizeImage;
    bfHeader.bfReserved1 = 0;
    bfHeader.bfReserved2 = 0;

    BYTE        *lpPal;

    lpPal = (BYTE *) pBitmapInfo;// 번지를 넘기죠 그 번지에 아래처럼 0-255까지의 GRAY VALUE를 저장하죠

    DWORD offDest = sizeof(BITMAPINFOHEADER);
    for(int i = 0; i < 256; i++)
    {
        lpPal[offDest++] = (BYTE)i;
        lpPal[offDest++] = (BYTE)i;
        lpPal[offDest++] = (BYTE)i;
        lpPal[offDest++] = 0x00;
    }
//자 이제부터는 저장만 하면됩니다.
    HANDLE fd= CreateFile
(strFileName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,NULL);

    if(!WriteFile(fd,(LPSTR)&bfHeader,sizeof(bfHeader),&len,NULL))
        AfxMessageBox("Err1");//Header저장

    size=((color-1) * sizeof(RGBQUAD)) + sizeof(BITMAPINFO);
    if(!WriteFile(fd,pBitmapInfo,size,&len,NULL))
        AfxMessageBox("Err2");//InfoHeader 저장

    BYTE * Image = new BYTE[width*height];// 신경쓰지 마세요
    MbufGet2d(MilImage,0,0,width,height,Image);//신경쓰지 마세요.. ^^
    if(!WriteFile(fd,Image,pBitmapInfo->bmiHeader.biSizeImage,&len,NULL))
        AfxMessageBox("Err3");//Imgae는 RAW이미지인데 전 1300*1030 카메라를 써서 MIL 라이브러리로 받았는데 여러분은 다르게 해도 됩니다. 암튼 Image는 raw이미지의 버퍼
    delete [] Image;
    delete pBitmapInfo;
    delete strFileName;
    CloseHandle(fd);
728x90
반응형

'프로그래밍 > MFC' 카테고리의 다른 글

오류 해결 - _CrtDbgReport: String too long or IO Error  (0) 2020.11.13
영상처리 - 미디언 필터  (0) 2020.11.13
Raw to BMP 설명  (0) 2020.11.12
GDI+ 기반 BMP to JPG  (0) 2020.11.12
BMP 저장  (0) 2020.11.12