|
감사합니다. 보여주신대로 하니 되네요..
감사합니다.................땡큐~땡큐~~~땓큐~~~~~
ㅂ 님이 쓰신 글 :
: 땅주인 님이 쓰신 글 :
: : 사진을 보시면 아시겠지만, 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가 자리하고 있습니다.
|