如何将CBitmap类中的内容存为BMP文件

ShenS 2000-03-09 10:18:00
加精
我已经在内存中建立了内存兼容的CBitmap对象,并在CBitmap中绘制了复杂的图形,使用Bitblt将该CBitmap显示到屏幕窗口中,但不知道如何将窗口中显示的内容存为硬盘上的BMP文件,请高手赐教!谢谢
...全文
289 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
longx 2000-03-09
  • 打赏
  • 举报
回复
将一个位图存进一个文件
需要分两步
1)将位图转换为与设备无关的DIB
DdbToDib(CBitmap& bitmap,DWORD dwcompression,CPalette* ppal )
2)将它写入文件中
BOOL WriteDib(LPCTSTR szfile, HANDLE hdib)

HANDLE DdbToDib(CBitmap& bitmap,DWORD dwcompression,CPalette* ppal )
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwlen;
HANDLE hdib;
HANDLE handle;
HDC hdc;
HPALETTE hpal;

ASSERT(bitmap.GetSafeHandle());
// the function has no arg for bitfields
if( dwcompression == BI_BITFIELDS)
return NULL;

// if a palette has not been supplied use defaul palette
hpal = (HPALETTE) ppal->GetSafeHandle();
if (hpal==NULL)
hpal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
// get bitmap information
bitmap.GetObject(sizeof(bm),(LPSTR)&bm);

// initialize the bitmapinfoheader
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression = dwcompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;

// compute the size of the infoheader and the color table
int ncolors = (1 << bi.biBitCount);
if( ncolors> 256 )
ncolors = 0;
dwlen = bi.biSize + ncolors * sizeof(RGBQUAD);

// we need a device context to get the dib from
hdc =::GetDC(NULL);
hpal = SelectPalette(hdc,hpal,FALSE);
RealizePalette(hdc);

// allocate enough memory to hold bitmapinfoheader and color table
hdib = GlobalAlloc(GMEM_FIXED,dwlen);

if (!hdib)
{
SelectPalette(hdc,hpal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
}

lpbi = (LPBITMAPINFOHEADER)hdib;

*lpbi = bi;

// call getdibits with a null lpbits param, so the device driver
// will calculate the bisizeimage field
GetDIBits(hdc, (HBITMAP )bitmap.GetSafeHandle(),0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS);

bi = *lpbi;

// if the driver did not fill in the bisizeimage field, then compute it
// each scan line of the image is aligned on a dword (32bit) boundary
if (bi.biSizeImage == 0)
{
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight;

// if a compression scheme is used the result may infact be larger
// increase the size to account for this.
if (dwcompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
}

// realloc the buffer so that it can hold all the bits
dwlen += bi.biSizeImage;
if (handle = GlobalReAlloc(hdib, dwlen, GMEM_MOVEABLE))
hdib = handle;
else
{
GlobalFree(hdib);
// reselect the original palette
SelectPalette(hdc,hpal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
}

// get the bitmap bits
lpbi = (LPBITMAPINFOHEADER)hdib;

// finally get the dib
int bgotbits =GetDIBits( hdc, (HBITMAP )bitmap.GetSafeHandle(),
0L, // start scan line
(DWORD)bi.biHeight, // # of scan lines
(LPBYTE)lpbi // address for bitmap bits
+ (bi.biSize + ncolors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // address of bitmapinfo
(DWORD)DIB_RGB_COLORS); // use rgb for color table

if( !bgotbits )
{
GlobalFree(hdib);
SelectPalette(hdc,hpal,FALSE);
::ReleaseDC(NULL,hdc);
return NULL;
}

SelectPalette(hdc,hpal,FALSE);
::ReleaseDC(NULL,hdc);
return hdib;
}

BOOL WriteDib(LPCTSTR szfile, HANDLE hdib)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi;

if (!hdib)
return FALSE;
CFile file;
if( !file.Open( szfile, CFile::modeCreate and CFile::modeWrite))
return FALSE;

lpbi = (LPBITMAPINFOHEADER)hdib;

int ncolors = 1 << lpbi->biBitCount;

// fill in the fields of the file header
hdr.bfType= ((WORD) ('M' << 8) and 'B');
hdr.bfSize=GlobalSize(hdib) + sizeof( hdr );
hdr.bfReserved1=0;
hdr.bfReserved2=0;
hdr.bfOffBits=(DWORD) (sizeof( hdr )+lpbi->biSize +ncolors * sizeof(RGBQUAD));
// write the file header
file.Write( &hdr, sizeof(hdr) );
// write the dib header and the bits
file.Write( lpbi, GlobalSize(hdib) );
return TRUE;
}

//以下程序演示利用上面的两个函数将一个CBitmap 对象写入文件中
CPalette pal;
CDC* dc=m_ShowPicture.GetDC();
if( dc->GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
{
UINT nsize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE* plp = (LOGPALETTE *) new BYTE[nsize];
plp->palVersion = 0x300;
plp->palNumEntries = GetSystemPaletteEntries(dc->m_hDC, 0, 255, plp->palPalEntry );
// create the palette
pal.CreatePalette( plp );
delete[] plp;
}
HANDLE hdib = DdbToDib(bitmap, BI_RGB, &pal );
if( hdib != NULL)
{
WriteDib(lpszFileName, hdib );
GlobalFree( hdib );
}

//以下程序演示利用上面的两个函数将一个CWnd 对象转化成位图文件写入文件中
CWnd* pWnd;
CBitmap pbitmap;
CWindowDC dc(pWnd);
CDC memdc;
CRect rect;

memdc.CreateCompatibleDC(&dc);
pWnd->GetWindowRect(rect);
pbitmap.CreateCompatibleBitmap(&dc, rect.Width(),rect.Height());

CBitmap* poldbitmap = memdc.SelectObject(&pbitmap);
memdc.BitBlt(0, 0, rect.Width(),rect.Height(), &dc, 0, 0, SRCCOPY);
CPalette pal;
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE)
{
UINT nsize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE* plp = (LOGPALETTE *) new BYTE[nsize];
plp->palVersion = 0x300;
plp->palNumEntries = GetSystemPaletteEntries(dc.m_hDC, 0, 255, plp->palPalEntry );
// create the palette
pal.CreatePalette( plp );
delete[] plp;
}
memdc.SelectObject(poldbitmap);
HANDLE hdib = DdbToDib(pbitmap, BI_RGB, &pal );
if( hdib != NULL)
{
WriteDib(lpszFileName, hdib );
GlobalFree( hdib );
}

zjy 2000-03-09
  • 打赏
  • 举报
回复
我E给你,有两套,分两次E出
告诉我E到哪个信箱
GoldenLion 2000-03-09
  • 打赏
  • 举报
回复
BMP文件格式首先是文件头,它的结构与BITMAPINFOHEAD比较类似,可以用CBitmap.GetBitmap()得到;随后是调色板,如果你是真彩图,那么就没有调色板;最后是数据区,它的值是调色板索引或者在真彩时就是RGB值。

找一个BMP文件,就能很清楚它的结构了。
snowhust 2000-03-09
  • 打赏
  • 举报
回复
zjy:能E给我一份吗? snowhust@cmmail.com
这是数字图像图形处理C源程序包2 31,mftab.zip 自由表格(63KB) 32,cimage.zip 一套图像处理程序,支持JPEG、GIF和PNG三种格式(892KB) 33,thinkr30.zip 简单的电子表格程序(141KB) 34,aseasy5.zip 另一个电子表格程序(319KB) 35,free.zip 一个电子表格程序,它能从脚本中处理数据(17KB) 36,iedit32.zip 在DOS中创建或编辑WINDOWS的图标(69KB) 37,giflt150.zip 保持GIF的可视面但减小它的大小25%(50KB) 38,gds31f.zip 观看,替换和转换 GIF/JPG/PCX/TIF/IFF/LBM/DL/ HAM/BMP/RLE/TGA/MAC/WPG/CUT/ANSI/TXT/IMG/ PBM/CUT/GL/FLI/MPG, 显示极小的图象(370KB) 39,fview10.zip 观看JPEG/GIF/TARGA 文件(72KB) 40,dta22b2.zip 从TGA文件创建FLI/FLC动画(254KB) 41,dfe-104.zip 显示字体编辑器能为EGA和VGA显示器创建新字体(219KB) 42,cmorph21.zip create morphed images with TGA/IMG/BMP/GIF/IPI/PCX files(630KB) 43,bmp2ico.zip 转换BMP文件到WINDOWS 3.X的ICO文件(22KB) 44,alch151.zip 图形转换器(359KB) 45,aaplay10.zip Autodesk Animator's FLI player(53KB) 46,a2r103.zip 转换ANSI 屏幕到RIP格式(17KB) 47,show204.zip GIF/PCX/JPEG 观察器(252KB) 48,bmp.zip 操纵位图的开发包(78KB) 49,draw_in.zip 在状态条里显现图(29KB) 50,cimageb.zip 读写jpg,dib文件的类。(267KB) 51,RGNC.zip 想制做超cool图形界面吗用它吧。(18KB) 52,CISBitmap.zip 这个从Cbitmap派生的位图类使你可以通过指定一种颜色把一幅位图变透明,而它的使用差不多同Cbitamp一样简单。(2KB) 53,Cdib.zip 这个类库可以实现设备无关位图的创建,显示,读入,保存,捕捉位图(6KB) 54,geotrans.zip 行程编码,JPEG压缩编码(基本系统)(32KB) 55,smooth.zip 图象的检测,模板匹配算法代码(24KB) 56,dither.zip 图象的边沿检测与提取,轮廓跟踪算法代码(24KB) 57,colorrope.zip 腐蚀,膨胀,细化算法代码(31KB) 58,morph.zip 直方图修正和彩色变换算法代码(17KB) 59,edge.zip 实现图案化和抖动技术以及bmp2txt源代码(34KB) 60,compress.zip 图象的几何变换算法(128KB) 61,tga2gif.zip TGA文件转换为GIF文件。(14KB) 62,tooltip.zip 可以多行显示的提示条(32KB) 63,yearmonth.zip 选择年/月的控制(39KB) 64,calen32a.zip 提供日历功能的动态库, 含有演示代码(79KB) 65,mappin.zip 你可以在你的GIS(地图信息系统)中使用这些源程序,因为它演示了在地图上的图钉效果,运行这个程序你可以在View中移动一些图标(286KB) 66,storage.zip 文件存储和流化的一些类(10KB) 67,Redraw.zip 克服控制闪烁问题(1KB)

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧