vc中的bmp
小弟在使用vc编制有关bmp图象的显示和保存时,实在是不会怎么保存了!
具体的情况是, 我先打开了一个bmp文件,然后把图象数据放到缓冲区里,然后打算使用通用
保存对话框来保存,可是总是不成功,希望那位大哥能不能指教一二,小弟先谢了
问题点数:60、回复次数:8Top
1 楼mmhhj()回复于 2002-03-04 20:00:09 得分 40
BOOL CDib::Save( const char *pszFilename )
{
// If we have no data, we can't save.
if( m_pDib == NULL )
return( FALSE );
CFile cf;
// Attempt to create the file.
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );
// Write the data.
try{
// First, create a BITMAPFILEHEADER
// with the correct data.
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD );
// Write the BITMAPFILEHEADER and the
// Dib data.
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pDib, m_dwDibSize );
}
// If we get an exception, delete the exception and
// return FALSE.
catch( CFileException *e ){
e->Delete();
return( FALSE );
}
return( TRUE );
}
BOOL CDib::Load( const char *pszFilename )
{
CFile cf;
m_delete=1;
// Attempt to open the Dib file for reading.
if( !cf.Open( pszFilename, CFile::modeRead ) )
return( FALSE );
// Get the size of the file and store
// in a local variable. Subtract the
// size of the BITMAPFILEHEADER structure
// since we won't keep that in memory.
DWORD dwDibSize;
dwDibSize =
cf.GetLength() - sizeof( BITMAPFILEHEADER );
// Attempt to allocate the Dib memory.
unsigned char *pDib;
pDib = new unsigned char [dwDibSize];
if( pDib == NULL )
return( FALSE );
BITMAPFILEHEADER BFH;
// Read in the Dib header and data.
try{
// Did we read in the entire BITMAPFILEHEADER?
if( cf.Read( &BFH, sizeof( BITMAPFILEHEADER ) )
!= sizeof( BITMAPFILEHEADER ) ||
// Is the type 'MB'?
BFH.bfType != 'MB' ||
// Did we read in the remaining data?
cf.Read( pDib, dwDibSize ) != dwDibSize ){
// Delete the memory if we had any
// errors and return FALSE.
delete [] pDib;
return( FALSE );
}
}
// If we catch an exception, delete the
// exception, the temporary Dib memory,
// and return FALSE.
catch( CFileException *e ){
e->Delete();
delete [] pDib;
return( FALSE );
}
// If we got to this point, the Dib has been
// loaded. If a Dib was already loaded into
// this class, we must now delete it.
if( m_pDib != NULL )
delete m_pDib;
// Store the local Dib data pointer and
// Dib size variables in the class member
// variables.
m_pDib = pDib;
m_dwDibSize = dwDibSize;
// Pointer our BITMAPINFOHEADER and RGBQUAD
// variables to the correct place in the Dib data.
m_pBIH = (BITMAPINFOHEADER *) m_pDib;
m_pPalette =
(RGBQUAD *) &m_pDib[sizeof(BITMAPINFOHEADER)];
// Calculate the number of palette entries.
m_nPaletteEntries = 1 << m_pBIH->biBitCount;
if( m_pBIH->biBitCount > 8 )
m_nPaletteEntries = 0;
else if( m_pBIH->biClrUsed != 0 )
m_nPaletteEntries = m_pBIH->biClrUsed;
// Point m_pDibBits to the actual Dib bits data.
m_pDibBits =
&m_pDib[sizeof(BITMAPINFOHEADER)+
m_nPaletteEntries*sizeof(RGBQUAD)];
// If we have a valid palette, delete it.
if( m_Palette.GetSafeHandle() != NULL )
m_Palette.DeleteObject();
// If there are palette entries, we'll need
// to create a LOGPALETTE then create the
// CPalette palette.
if( m_nPaletteEntries != 0 ){
// Allocate the LOGPALETTE structure.
LOGPALETTE *pLogPal = (LOGPALETTE *) new char
[sizeof(LOGPALETTE)+
m_nPaletteEntries*sizeof(PALETTEENTRY)];
if( pLogPal != NULL ){
// Set the LOGPALETTE to version 0x300
// and store the number of palette
// entries.
pLogPal->palVersion = 0x300;
pLogPal->palNumEntries = m_nPaletteEntries;
// Store the RGB values into each
// PALETTEENTRY element.
for( int i=0; i<m_nPaletteEntries; i++ ){
pLogPal->palPalEntry[i].peRed =
m_pPalette[i].rgbRed;
pLogPal->palPalEntry[i].peGreen =
m_pPalette[i].rgbGreen;
pLogPal->palPalEntry[i].peBlue =
m_pPalette[i].rgbBlue;
}
// Create the CPalette object and
// delete the LOGPALETTE memory.
m_Palette.CreatePalette( pLogPal );
delete [] pLogPal;
}
}
return( TRUE );
}
class AFX_EXT_CLASS CDib
{
public:
CDib();
~CDib();
BOOL Load( const char * );
BOOL Save( const char * );
BOOL Draw( CDC *, int nX = 0, int nY = 0, int nWidth = -1, int nHeight = -1 );
BOOL SetPalette( CDC * );
void FadeGrayScaleToColor( CDC *pDC,int xDest, int yDest, int nLoops,int nDelay ) ;
void SetDibs(HGLOBAL dib,int);
BOOL m_delete;
private:
CPalette m_Palette;
unsigned char *m_pDib, *m_pDibBits;
DWORD m_dwDibSize;
BITMAPINFOHEADER *m_pBIH;
RGBQUAD *m_pPalette;
int m_nPaletteEntries;
};
Top
2 楼why_no1(纯开罗)回复于 2002-03-04 21:14:42 得分 0
mmhhj() 兄,如果位图换成图标,该怎么解决?Top
3 楼qiangqiang1112(强强)回复于 2002-03-06 17:41:44 得分 0
mmhhj()大哥,我的机器有点问题,现在还不能给你分数,明天或者后天我会补上的,
还有就是我怎么运行不成功呢???
Top
4 楼hhoking(妙手仁心)回复于 2002-03-06 18:56:28 得分 20
不用那么麻烦吧?我是这样写的:
bool DIB::Save(const char *pFileName)
{
if (m_pDibData == NULL)
{
return (false);
}
CFile bmpFile;
if (!bmpFile.Open(pFileName,CFile::modeCreate|CFile::modeWrite))
{
m_nDibError = OPEN_EXCEPTION;
return (false);
}
try
{
BITMAPFILEHEADER BFH;
BFH.bfType = 'MB';
BFH.bfSize = sizeof(BITMAPFILEHEADER) + m_DibSize;
BFH.bfReserved1 = 0X0000;
BFH.bfReserved2 = 0X0000;
BFH.bfOffBits = sizeof(BITMAPFILEHEADER) +
sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * m_nColorTableNumber;
bmpFile.Write(&BFH, sizeof(BITMAPFILEHEADER));
bmpFile.Write(m_pDibData, m_DibSize);
}
catch (CFileException *e)
{
m_nDibError = WRITE_EXCEPTION;
e->Delete();
return (false);
}
return (true);
}Top
5 楼hhoking(妙手仁心)回复于 2002-03-06 19:00:56 得分 0
Sorry,我没仔细看上面仁兄给出的是全部的代码,不好意思,以为只是个Save。
qiangqiang1112 (强强):如果留有Mail,我可以转给你一份完整的工程,有详细的注释,你可以自己慢慢看。Top
6 楼hhoking(妙手仁心)回复于 2002-03-06 19:02:52 得分 0
图标是一样的,按图标的格式得到相关指针,最终还是显示的BMP。Top
7 楼why_no1(纯开罗)回复于 2002-03-07 21:39:40 得分 0
图标是什么格式?在哪儿能找到这方面的例子呢?Top
8 楼qiangqiang1112(强强)回复于 2002-03-10 20:07:41 得分 0
我的e-mail是dacular_ff@chinaren.com
谢谢您了Top




