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;
}
}