C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[48271] Re:[변경] RAW=>BITMAP하였을 때 색상이 달라지는 이유?
[] 1971 읽음    2007-03-02 20:23
땅주인 님이 쓰신 글 :
: 사진을 보시면 아시겠지만, Capture로 잡은 이미지 색상이 달라집니다.
:
: USB CAM에서 이미지를 입력받은 RAW DATA <=> BITMAP <=> JPEG 로 변환하는 로직을 짜고 있는데요..
: RAW 데이터를 BITMAP으로 변환 해서 화면에 찍으면 색상이 변해서 나오는데..이유를 모르겠습니다.
: 아시는 분 답변 좀 바랍니다. RGB의 순서가 바뀌었다거나 색상정보가 하나 빠졌다거나..뭐 그런 것 같은데..
:
: 감사합니다.
:
: BYTE FrameMemory[160*120*3];
: static BITMAPINFO m_sBmpHeaderDefault = {{0x28,160,120,1,8*3,0,160*120*3,0,0,0,0},{0,0,0,0}};
:
: LRESULT CALLBACK capVideoStreamCallback(HWND hWnd, LPVIDEOHDR lpVHdr)
: {
:     memcpy(FrameMemory,lpVHdr->lpData,160*120*3);
:     return (LRESULT)TRUE;
: }
: .....
: .....
:
: // USB CAM 초기화 하는 루틴 =============================================================
:
:   HWND m_hWndCap;
:   m_hWndCap = capCreateCaptureWindow("Capture Window", WS_CHILD|WS_VISIBLE|WS_DISABLED,
:                                   8, 16, 160,120,this->Handle, 0);
:   capSetCallbackOnFrame(m_hWndCap, capVideoStreamCallback);
:   if(!capDriverConnect(m_hWndCap, 0))
:    {   // Number of Video Device Driver
:      Application->MessageBox("Video Device Driver not found!", NULL, MB_OKCANCEL);
:    }
:   CAPDRIVERCAPS driverCaps;
:   capDriverGetCaps(m_hWndCap, &driverCaps, sizeof(driverCaps));
:
:   // Format
:   if(!capSetVideoFormat(m_hWndCap, &m_sBmpHeaderDefault, sizeof(BITMAPINFO)))  // Video Format 지정
:    {
:     capDriverDisconnect(m_hWndCap);
:     ::DestroyWindow(m_hWndCap);
:     return;
:    };
:
: // Preview Frame Interval
:    capPreviewRate(m_hWndCap, (UINT)(1000.0/8));
:    capPreview(m_hWndCap, TRUE);
: }
:
:
: // ====================================================================
: // 이미지 켑쳐하는 로직
: // ====================================================================
:
: // BITMAPFILEHEADER  정보를 만들어 줌..
:
:     BITMAPFILEHEADER Bmfh;
:     Bmfh.bfType          = 0x4d42;   // BM => Bitmap file
:     Bmfh.bfSize          = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +  // file size
:                                    sizeof(RGBQUAD) + 160 * 120 * 3 - 2; // -2를 하지 않으면 에러 남
:     Bmfh.bfReserved1     = 0;   // not use
:     Bmfh.bfReserved2     = 0;   // not use
:     Bmfh.bfOffBits       = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
:                                    sizeof(RGBQUAD) - 2; // -2를 하지 않으면 에러 남
:                           
:     BYTE *p = new BYTE[Bmfh.bfSize];   // BITMAP을 담을 공간 생성
:
: // BITMAPFILEHEADER 정보-----------------------------------------------
:
:     int iPos = 0;
:     memcpy(p, &Bmfh.bfType,      sizeof(Bmfh.bfType));
:     iPos += sizeof(Bmfh.bfType);
:     memcpy(p + iPos , &Bmfh.bfSize,      sizeof(Bmfh.bfSize));
:     iPos += sizeof(Bmfh.bfSize);
:     memcpy(p + iPos, &Bmfh.bfReserved1, sizeof(Bmfh.bfReserved1));
:     iPos += sizeof(Bmfh.bfReserved1);
:     memcpy(p + iPos, &Bmfh.bfReserved2, sizeof(Bmfh.bfReserved2));
:     iPos += sizeof(Bmfh.bfReserved2);
:     memcpy(p + iPos, &Bmfh.bfOffBits,   sizeof(Bmfh.bfOffBits));
:     iPos += sizeof(Bmfh.bfOffBits);
:
: // BITMAPINFO 정보 ------------------------------------------------------
:
:     memcpy(p + iPos, &m_sBmpHeaderDefault, sizeof(m_sBmpHeaderDefault));  
:     iPos += sizeof(m_sBmpHeaderDefault);
:
:     memcpy(p + iPos, FrameMemory, sizeof(FrameMemory));   // RAW데이터 복사
:
:     TMemoryStream *pMemoryStream = new TMemoryStream();
:     pMemoryStream->WriteBuffer(p,Bmfh.bfSize);
:     pMemoryStream->Position = 0;
:     Graphics::TBitmap *pBitmap = new Graphics::TBitmap();
:     pBitmap->LoadFromStream(pMemoryStream);
:     pMemoryStream->Position = 0;
:
:     Image1->Picture->Bitmap->LoadFromStream(pMemoryStream);
:
:     if ( m_pJpgPhoto == NULL ) {
:         m_pJpgPhoto = new TJPEGImage();
:     }
:     m_pJpgPhoto->Assign(Image1->Picture->Bitmap);
:
: 제발 좋은 답변 있기를...


void __fastcall TForm1::ShowFrame(LPVIDEOHDR lpVHdr)
{
// ====================================================================
// 이미지 켑쳐하는 로직
// ====================================================================
// BITMAPFILEHEADER  정보를 만들어 줌..
    BITMAPFILEHEADER Bmfh;
    Bmfh.bfType          = 0x4d42;   // BM => Bitmap file
    Bmfh.bfSize          = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lpVHdr->dwBytesUsed;
    Bmfh.bfReserved1     = 0;   // not use
    Bmfh.bfReserved2     = 0;   // not use
    Bmfh.bfOffBits       = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

    TMemoryStream *pMemoryStream = new TMemoryStream();
    pMemoryStream->WriteBuffer(&Bmfh,sizeof(Bmfh));
    pMemoryStream->WriteBuffer(&m_sBmpHeaderDefault, sizeof(BITMAPINFOHEADER));
    pMemoryStream->WriteBuffer(lpVHdr->lpData, lpVHdr->dwBytesUsed);

    pMemoryStream->Position = 0;
    Image1->Picture->Bitmap->LoadFromStream(pMemoryStream);
    delete pMemoryStream;
}

TBitmap에서는 BITMAPFILEHEADER의 bfOffBits에 지정된 값을 인정해주지 않는것으로 보입니다.

bfOffBits의 값은 나머지 정보들로부터 계산해낼 수 있는데  TBitmap에서는 이렇게 직접 계산한 것을 사용하는 모양입니다.

위와 같은 배경에서 보면, 제시하신 코드에서 BITMAPINFO의 bmiColors는 불필요한 데이터입니다.

TBitmap 내부 코드에서 계산한 bfOffBits의 값은 BITMAPINFOHEADER의 끝 바로 다음을 가리키고 있고 그 곳에서 이미지 데이터가 시작되는 것으로 처리하는 것으로 보입니다.

제시하신 코드에서 그 위치에는 불필요한 RGBQUAD가 자리하고 있습니다.

+ -

관련 글 리스트
48257 [변경] RAW=>BITMAP하였을 때 색상이 달라지는 이유? 땅주인 1726 2007/03/02
48271     Re:[변경] RAW=>BITMAP하였을 때 색상이 달라지는 이유? 1971 2007/03/02
48273         Re:Re:[변경] RAW=>BITMAP하였을 때 색상이 달라지는 이유? 땅주인 2507 2007/03/03
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.