2012-09-08 2 views
1

메모리 DC를 비트 맵 파일에 저장하려고했습니다.hdc를 비트 맵에 올바르게 저장할 수 없습니다.

infoHeader.biSizeImage 

fileHeader.bfSize 


fileHeader.bfOffBits 

WriteFile(hFile, &fileHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); 

WriteFile(hFile, &infoHeader, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); 

WriteFile(hFile, pPixels, info.bmiHeader.biSizeImage, &dwBytesWritten, NULL); 

내가 파일을 얻을 수 있지만, 그것이 깨진 없거나 더 이상 지원 불평 때문에 나는 그것을 열 수 없습니다 :하지만 다음과 같은 사항에 대해 크기에 대한 올바른 값을 얻을 수 없습니다.

bmp에 저장하는 방법은 여러 가지가 있지만 크기가 다른 값이 많습니다. 일부는 팔레트 정보도 포함합니다. 나는 완전히 혼란 스럽다.

누군가 올바른 정보를 입력하는 방법을 나타낼 수 있습니까?

static void SaveAsBmp(TCHAR *fileName) 
{ 
HDC hdcView = GetDC(hwndView); 
HDC memDC = CreateCompatibleDC(hdcView); 

RECT rcView; 
GetClientRect(hwndView, &rcView); 

int rcView_dx = rcView.right - rcView.left; 
int rcView_dy = rcView.bottom - rcView.top; 

HBITMAP hMemBmp = CreateCompatibleBitmap(hdcView, rcView_dx, rcView_dy); 
HBITMAP hOldBmp = (HBITMAP)SelectObject(memDC, hMemBmp); 

BitBlt(memDC, 0, 0, rcView_dx, rcView_dy, hdcView, 0, 0, SRCCOPY); 

//---------- 

BITMAP bmp; 
GetObject(hMemBmp, sizeof(BITMAP), &bmp); 

//---------- 

WORD wBits = (WORD)(bmp.bmBitsPixel * bmp.bmPlanes); 

if(wBits <= 1)             
    wBits = 1;    
else if(wBits <= 4)        
    wBits = 4;    
else if(wBits <= 8)        
    wBits = 8;    
else if (wBits <= 16) 
    wBits = 16; 
else if (wBits <= 24) 
    wBits = 24; 
else wBits = 32; 

//---------- 

BITMAPINFOHEADER infoHeader; 
BITMAPINFO info; 
info.bmiHeader = infoHeader; 

infoHeader.biSize = sizeof(BITMAPINFOHEADER);  
infoHeader.biWidth = bmp.bmWidth; 
infoHeader.biHeight = bmp.bmHeight;  
infoHeader.biPlanes = bmp.bmPlanes;  
infoHeader.biBitCount = bmp.bmBitsPixel;  
infoHeader.biCompression = BI_RGB; 

infoHeader.biSizeImage = 2 * ((bmp.bmWidth * bmp.bmBitsPixel + 15)/16) * bmp.bmPlanes * bmp.bmHeight; 
infoHeader.biXPelsPerMeter = 0; 
infoHeader.biYPelsPerMeter = 0; 
infoHeader.biClrUsed = 0; 
infoHeader.biClrImportant = 0; 

RGBQUAD *pPixels = new RGBQUAD[bmp.bmWidth * bmp.bmWidth]; 
GetDIBits(memDC, hMemBmp, 0, bmp.bmWidth, pPixels, &info, DIB_RGB_COLORS); 

BITMAPFILEHEADER fileHeader; 
fileHeader.bfType = 0x4d42; 
fileHeader.bfSize = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + info.bmiHeader.biSizeImage); 
fileHeader.bfReserved1 = 0; 
fileHeader.bfReserved2 = 0; 
fileHeader.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + info.bmiHeader.biSize); 

HANDLE hFile = CreateFile(fileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

DWORD dwBytesWritten; 

WriteFile(hFile, &fileHeader, sizeof(BITMAPFILEHEADER), &dwBytesWritten, NULL); 
WriteFile(hFile, &infoHeader, sizeof(BITMAPINFOHEADER), &dwBytesWritten, NULL); 
WriteFile(hFile, pPixels, info.bmiHeader.biSizeImage, &dwBytesWritten, NULL); 

CloseHandle(hFile); 

delete pPixels; 

SelectObject(memDC, hOldBmp); 
DeleteObject(hMemBmp); 
DeleteDC(memDC); 

답변

0

infoHeader.biSizeImage은 = 2 * ((bmp.bmWidth * bmp.bmBitsPixel는 + 15)/16) * * bmp.bmPlanes bmp.bmHeight;

는 24 또는 32이 즉, 픽셀 당 비트 그리고 그것은 픽셀 당 바이트 인 것처럼 당신이 그것을 사용하는 가정하고,이 bmp.bmBitsPixel >> 3해야한다, 바로 여기에 보이지 않는다.

일반적으로 코드가 좋게 보이기 때문에 디버거로 변수를 검사하여 불일치를 찾아야합니다 (또는 여기에 붙여 넣기, 특히 BITMAPINFOHEADER).

CreateCompatibleBitmap을 사용하는 대신 012b을 사용하여 24 bpp RGB와 같이 관심있는 형식으로 사용할 수 있습니다.이 경우 원시 비트를 즉시 수신합니다 . 그런 다음 데이터를이 비트 맵에 블리 칭하면 GetObject이 필요 없으므로 이미 필요한 모든 것이 있으므로 더 이상 호출 할 필요가 없습니다. 그리고 GetObject은 이미 BITMAPINFOHEADER을 사용할 준비가 된 DIBSECTION 형식을 반환 할 수 있습니다. 그것은 모두 동일하고, 단순합니다.

+0

마지막으로 http://msdn.microsoft.com/en-us/library/windows/desktop/dd145119%28v=vs.85%29.aspx를 사용하십시오. – user565739