void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) { HANDLE hf; // file handle BITMAPFILEHEADER hdr; // bitmap file-header PBITMAPINFOHEADER pbih; // bitmap info-header LPBYTE lpBits; // memory pointer DWORD dwTotal; // total count of bytes DWORD cb; // incremental count of bytes BYTE *hp; // byte pointer DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) errhandler("GlobalAlloc", hwnd); // Retrieve the color table (RGBQUAD array) and the bits // (array of palette indices) from the DIB. if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) { errhandler("GetDIBits", hwnd); } // Create the .BMP file. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) errhandler("CreateFile", hwnd); hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); // Copy the BITMAPFILEHEADER into the .BMP file. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) { errhandler("WriteFile", hwnd); } // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL)) errhandler("WriteFile", hwnd); // Copy the array of color indices into the .BMP file. dwTotal = cb = pbih->biSizeImage; hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) errhandler("WriteFile", hwnd); // Close the .BMP file. if (!CloseHandle(hf)) errhandler("CloseHandle", hwnd); // Free memory. GlobalFree((HGLOBAL)lpBits); }
void CreateBMPFile(HWND hwnd, LPTSTR pszFile, PBITMAPINFO pbi, HBITMAP hBMP, HDC hDC) { HANDLE hf; // file handle BITMAPFILEHEADER hdr; // bitmap file-header PBITMAPINFOHEADER pbih; // bitmap info-header LPBYTE lpBits; // memory pointer DWORD dwTotal; // total count of bytes DWORD cb; // incremental count of bytes BYTE *hp; // byte pointer DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi; lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits) errhandler("GlobalAlloc", hwnd); // Retrieve the color table (RGBQUAD array) and the bits // (array of palette indices) from the DIB. if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi, DIB_RGB_COLORS)) { errhandler("GetDIBits", hwnd); } // Create the .BMP file. hf = CreateFile(pszFile, GENERIC_READ | GENERIC_WRITE, (DWORD) 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, (HANDLE) NULL); if (hf == INVALID_HANDLE_VALUE) errhandler("CreateFile", hwnd); hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M" // Compute the size of the entire file. hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof(RGBQUAD) + pbih->biSizeImage); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; // Compute the offset to the array of color indices. hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) + pbih->biSize + pbih->biClrUsed * sizeof (RGBQUAD); // Copy the BITMAPFILEHEADER into the .BMP file. if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER), (LPDWORD) &dwTmp, NULL)) { errhandler("WriteFile", hwnd); } // Copy the BITMAPINFOHEADER and RGBQUAD array into the file. if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER) + pbih->biClrUsed * sizeof (RGBQUAD), (LPDWORD) &dwTmp, ( NULL)) errhandler("WriteFile", hwnd); // Copy the array of color indices into the .BMP file. dwTotal = cb = pbih->biSizeImage; hp = lpBits; if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL)) errhandler("WriteFile", hwnd); // Close the .BMP file. if (!CloseHandle(hf)) errhandler("CloseHandle", hwnd); // Free memory. GlobalFree((HGLOBAL)lpBits); }
得到BMP数据后,可以用下面这个函数获得HBITMAPThe SetDIBits function sets the pixels in a bitmap using the color data found in the specified DIB . int SetDIBits( HDC hdc, // handle to DC HBITMAP hbmp, // handle to bitmap UINT uStartScan, // starting scan line UINT cScanLines, // number of scan lines CONST VOID *lpvBits, // array of bitmap bits CONST BITMAPINFO *lpbmi, // bitmap data UINT fuColorUse // type of color indexes to use );
HBITMAP hBMP, HDC hDC)
{
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits)
errhandler("GlobalAlloc", hwnd); // Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
errhandler("GetDIBits", hwnd);
} // Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE)
errhandler("CreateFile", hwnd);
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0; // Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD); // Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL))
{
errhandler("WriteFile", hwnd);
} // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL))
errhandler("WriteFile", hwnd); // Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
errhandler("WriteFile", hwnd); // Close the .BMP file.
if (!CloseHandle(hf))
errhandler("CloseHandle", hwnd); // Free memory.
GlobalFree((HGLOBAL)lpBits);
}
HBITMAP hBMP, HDC hDC)
{
HANDLE hf; // file handle
BITMAPFILEHEADER hdr; // bitmap file-header
PBITMAPINFOHEADER pbih; // bitmap info-header
LPBYTE lpBits; // memory pointer
DWORD dwTotal; // total count of bytes
DWORD cb; // incremental count of bytes
BYTE *hp; // byte pointer
DWORD dwTmp; pbih = (PBITMAPINFOHEADER) pbi;
lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizeImage); if (!lpBits)
errhandler("GlobalAlloc", hwnd); // Retrieve the color table (RGBQUAD array) and the bits
// (array of palette indices) from the DIB.
if (!GetDIBits(hDC, hBMP, 0, (WORD) pbih->biHeight, lpBits, pbi,
DIB_RGB_COLORS))
{
errhandler("GetDIBits", hwnd);
} // Create the .BMP file.
hf = CreateFile(pszFile,
GENERIC_READ | GENERIC_WRITE,
(DWORD) 0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
(HANDLE) NULL);
if (hf == INVALID_HANDLE_VALUE)
errhandler("CreateFile", hwnd);
hdr.bfType = 0x4d42; // 0x42 = "B" 0x4d = "M"
// Compute the size of the entire file.
hdr.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof(RGBQUAD) + pbih->biSizeImage);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0; // Compute the offset to the array of color indices.
hdr.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +
pbih->biSize + pbih->biClrUsed
* sizeof (RGBQUAD); // Copy the BITMAPFILEHEADER into the .BMP file.
if (!WriteFile(hf, (LPVOID) &hdr, sizeof(BITMAPFILEHEADER),
(LPDWORD) &dwTmp, NULL))
{
errhandler("WriteFile", hwnd);
} // Copy the BITMAPINFOHEADER and RGBQUAD array into the file.
if (!WriteFile(hf, (LPVOID) pbih, sizeof(BITMAPINFOHEADER)
+ pbih->biClrUsed * sizeof (RGBQUAD),
(LPDWORD) &dwTmp, ( NULL))
errhandler("WriteFile", hwnd); // Copy the array of color indices into the .BMP file.
dwTotal = cb = pbih->biSizeImage;
hp = lpBits;
if (!WriteFile(hf, (LPSTR) hp, (int) cb, (LPDWORD) &dwTmp,NULL))
errhandler("WriteFile", hwnd); // Close the .BMP file.
if (!CloseHandle(hf))
errhandler("CloseHandle", hwnd); // Free memory.
GlobalFree((HGLOBAL)lpBits);
}
HDC hdc, // handle to DC
HBITMAP hbmp, // handle to bitmap
UINT uStartScan, // starting scan line
UINT cScanLines, // number of scan lines
CONST VOID *lpvBits, // array of bitmap bits
CONST BITMAPINFO *lpbmi, // bitmap data
UINT fuColorUse // type of color indexes to use
);
看这个
具体说清楚点,那是什么数据的指针?
是整个BMP数据(BITMAPINFO & BitsData)还是只是些原始的raw数据?
那太简单了,如果没有fileheader的话,自己填写就可以保存了..like:#define WIDTHBYTES(w,b) ( ( ( ( w ) * ( b ) + 31 ) >> 5 ) << 2 )BOOL Save( LPCTSTR lpszFileName /*文件名*/, LPBYTE lpBMP/*你的指针*/ )
{
CFile file;
if( !file.Open( lpszFileNaem, CFile::modeCreate|CFile::modeWrite ) )
return FALSE;
BITMAPFILEHEADER bmfh;
LPBITMAPINFOHEADER lpBmih = ( LPBITMAPINFOHEADER )lpBMP;
if( lpBmih == NULL )
return FALSE;
memset( &bmfh, 0x0, sizeof( BITMAPFILEHEADER ) );
DWORD dwColors = lpBmih->biBitCount <= 8 ? 1 << lpBmih->biBitCount : 0;
if( lpBmih->biCompression == BI_BITFIELD )
dwColors = 3;
DWORD dwInfoSize = sizeof( BITMAPINFOHEADER ) + dwColors * sizeof( RGBQUAD );
DWORD dwImageSize = WIDTHBYTES( llpBmih->biWidth, lpBmih->biBitCount ) * lpBmih->biHeight; bmfh.bfType = 0x4d42;
bmfh.bfSize = sizeof( BITMAPFILEHEADER ) + dwInfoSize + dwImageSize;
bmfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + dwInfoSize;
file.Write( &bmfh, sizeof( BITMAPFILEHEADER ) );
fiel.WriteHuge( lpBMP, dwInfoSize+dwImageSize );
return TRUE;
}
谢谢你的代码,我在试你的代码的时候,在最后的写入中,触发了异常,说不能访问我创建的图片文件。 CFile file;
file.Open( L"1.bmp", CFile::modeCreate|CFile::modeWrite ); BITMAPFILEHEADER bmfh;
LPBITMAPINFOHEADER lpBmih = ( LPBITMAPINFOHEADER )DestBuf; memset( &bmfh, 0x0, sizeof( BITMAPFILEHEADER));
DWORD dwColors = lpBmih->biBitCount <= 8 ? 1 << lpBmih->biBitCount : 0;
if( lpBmih->biCompression == BI_BITFIELDS )
dwColors = 3;
DWORD dwInfoSize = sizeof( BITMAPINFOHEADER ) + dwColors * sizeof( RGBQUAD );
DWORD dwImageSize = WIDTHBYTES( lpBmih->biWidth, lpBmih->biBitCount ) * lpBmih->biHeight; bmfh.bfType = 0x4d42;
bmfh.bfSize = sizeof( BITMAPFILEHEADER ) + dwInfoSize + dwImageSize;
bmfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + dwInfoSize;
file.Write( &bmfh, sizeof( BITMAPFILEHEADER ) );
file.Write( &DestBuf, dwInfoSize+dwImageSize );
那你的那个指针估计有问题,如下修改试试:
BOOL Save( LPCTSTR lpszFileName /*文件名*/, LPBYTE lpBMP/*你的指针*/ )
{
CFile file;
if( !file.Open( lpszFileNaem, CFile::modeCreate|CFile::modeWrite ) )
return FALSE;
BITMAPFILEHEADER bmfh;
LPBITMAPINFOHEADER lpBmih = ( LPBITMAPINFOHEADER )lpBMP;
if( lpBmih == NULL )
return FALSE;
// add this..
if( lpBmih->biSize != sizeof( BITMAPINFOHEADER ){
MessageBox( NULL, "错误:不是位图数据! , "ERROR!", MB_OK );
return FALSE;
}
memset( &bmfh, 0x0, sizeof( BITMAPFILEHEADER ) );
DWORD dwColors = lpBmih->biBitCount <= 8 ? 1 << lpBmih->biBitCount : 0;
if( lpBmih->biCompression == BI_BITFIELD )
dwColors = 3;
DWORD dwInfoSize = sizeof( BITMAPINFOHEADER ) + dwColors * sizeof( RGBQUAD );
DWORD dwImageSize = WIDTHBYTES( lpBmih->biWidth, lpBmih->biBitCount ) * lpBmih->biHeight; bmfh.bfType = 0x4d42;
bmfh.bfSize = sizeof( BITMAPFILEHEADER ) + dwInfoSize + dwImageSize;
bmfh.bfOffBits = sizeof( BITMAPFILEHEADER ) + dwInfoSize;
file.Write( &bmfh, sizeof( BITMAPFILEHEADER ) );
fiel.WriteHuge( lpBMP, dwInfoSize+dwImageSize );
return TRUE;
}
fopen(...);
fwrite(...);
fclose(..);这样就可以了。楼上给的是读取BMP的方法