CAFE

2015동계 SCS교육

bmp파일을 읽어 raw 데이터를 추출한 후 dc 화면에 그리기

작성자한창호|작성시간16.01.13|조회수5,273 목록 댓글 0


1. bmp 파일을 읽어서 raw 데이터 입력한다.


사용예) 


#define WIDTHBYTES(bits)   (((bits)+31)/32*4)  // 4바이트 배수


BYTE *m_pImgBuff = NULL;


CClientDC dc(this);

LoadBMPIntoDC(&dc, "test.bmp");


bool LoadBMPIntoDC ( HDC hDC, LPCTSTR bmpfile )
{
  // check if params are valid
  if ( ( NULL == hDC  ) || ( NULL == bmpfile ) )
  return false;     
 
  // load bitmap into a bitmap handle
  HANDLE hBmp = LoadImage ( NULL, bmpfile, IMAGE_BITMAP, 0, 0,
  LR_LOADFROMFILE | LR_CREATEDIBSECTION );
 
  if ( NULL == hBmp )
    return false;        // failed to load image


  
 // now get the bmp size
 BITMAP bm;
 GetObject ( hBmp, sizeof(bm), &bm );

 BYTE* pdata = (BYTE*)bm.bmBits;


 if(pdata!=NULL) {
  if(m_pImgBuff==NULL) m_pImgBuff = new BYTE[bm.bmWidthBytes*bm.bmHeight];
  memcpy(m_pImgBuff, pdata, bm.bmWidthBytes*bm.bmHeight);
 }

 DeleteObject(hBmp);


 // dc에 그리기

CDC* pDC = CDC::FromHandle(hDC);

 DrawRawDataIntoDC( pDC, m_pImgBuff,400,10, bm.bmWidth,bm.bmHeight, bm.bmBitPixel);


 return true;
}



2. Raw 데이터를 dc 화면에 그리기


버튼을 누르면 raw 데이터인 m_pImgBuff를 출력한다.


void CReal_checkDlg::OnButton1()
{
 // TODO: Add your control notification handler code here
 CClientDC dc(this);
 DrawRawDataIntoDC(&dc, m_pImgBuff,400,10, 640,480,24);
}


 void DrawRawDataIntoDC(CDC* pDC, BYTE* pViewImg,int x,int y, int width,int height,int bitCount)
{
 BITMAPINFO *pBmpInfo = NULL;
 if(pBmpInfo != NULL)
 {
  delete [] pBmpInfo;
  pBmpInfo = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))];
 } else   
  pBmpInfo = (BITMAPINFO*) new BYTE[sizeof(BITMAPINFOHEADER) + (256 * sizeof(RGBQUAD))];
 

 pBmpInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 pBmpInfo->bmiHeader.biPlanes = 1;
 pBmpInfo->bmiHeader.biCompression = 0; //BI_RGB;// 0; 
 pBmpInfo->bmiHeader.biWidth = width; //이미지 가로 크기를 적음. 
 pBmpInfo->bmiHeader.biHeight = height;
 pBmpInfo->bmiHeader.biBitCount = bitCount;
 pBmpInfo->bmiHeader.biXPelsPerMeter = 0;
 pBmpInfo->bmiHeader.biYPelsPerMeter = 0;
 pBmpInfo->bmiHeader.biClrUsed = 256;
 pBmpInfo->bmiHeader.biClrImportant = 0;//SHRT_MAX; 
 pBmpInfo->bmiHeader.biSizeImage =height * WIDTHBYTES( width * bitCount );
 
 if(bitCount==8)
 {
  for(int i = 0; i < 256; i++)
  {
   pBmpInfo->bmiColors[i].rgbBlue = i;
   pBmpInfo->bmiColors[i].rgbGreen = i;
   pBmpInfo->bmiColors[i].rgbRed = i;
   pBmpInfo->bmiColors[i].rgbReserved= 0;
  }
 }


 //pViewImg 가 RAW DATA
 if(pViewImg != NULL)
 {
  //화면에 출력하기 전에 메모리에 먼저 적재한다. 또한, 비트맵 구조체를 만든다. 
  CRect rect;
  CDC memDC;
  CBitmap bitMap, *pOldBitmap;

  // 호환되는 memDC를 메모리에 생성한다. 
  memDC.CreateCompatibleDC(pDC);
  bitMap.CreateCompatibleBitmap(pDC, width, height);
  pOldBitmap = (CBitmap*)memDC.SelectObject(&bitMap);
  memDC.SelectObject(&bitMap);
  memDC.FillSolidRect(&rect, RGB(255, 255, 255));

  // image 역상
  
  int rwsize = WIDTHBYTES(width * bitCount );
  for (int i=0; i<height/2; i++) {
   for (int j=0; j<width*3; j++) {
    char temp = pViewImg[i*rwsize+j];
    pViewImg[i*rwsize+j] = pViewImg[(height-i-1)* rwsize + j] ;
    pViewImg[(height-i-1)* rwsize + j]  = temp;    
   }
  }

  
  SetDIBitsToDevice(
   memDC.GetSafeHdc(), // Handle to the device context. 
   0, 0, // Specifies the x and y-coordinate, in logical units, of the upper-left corner of the destination rectangle. 
   width, height, //가로, 세로를 적는다. 
   // Specifies the width and height, in logical units, of the DIB. 
   0, 0, // Specifies the x and y-coordinate, in logical units, of the lower-left corner of the DIB. 
   0, // Specifies the starting scan line in the DIB. 
   height, //세로를 적음. // Specifies the number of DIB scan lines contained in the array pointed to by the lpvBits parameter. 
   pViewImg, pBmpInfo, DIB_RGB_COLORS);


  //StretchBltMode 설정. 
  pDC->SetStretchBltMode(COLORONCOLOR);
  
  //dc.BitBlt(0, 0, rectLP.right, rectLP.bottom, &memDC,0, 0, SRCCOPY); 


  //pDC->StretchBlt(0,0,Width, Height, &memDC, 0, 0, Width, Height, SRCCOPY);   //크기조절 가능하다.
  pDC->BitBlt(x,y,width, height, &memDC, 0,0,SRCCOPY);
  
 }


 if(pBmpInfo != NULL)
 {
  delete [] pBmpInfo;
  pBmpInfo = NULL;
 }
}




다음검색
현재 게시글 추가 기능 열기
  • 북마크
  • 공유하기
  • 신고하기

댓글

댓글 리스트
맨위로

카페 검색

카페 검색어 입력폼