bitmap 处理问题

tyzyx 2009-06-23 11:21:04
对于图像处理是新手,问题可能很简单,希望各位能详细回答
想要剪裁bitmap的某个矩形区域,保存到Cbitmap对象,并写入到文件中,代码如下

CBitmap bitmapdes,bitmapsrc;
CString filename;
HDC m_hMemDC;
LONG m_nWidth,m_nHeight;
CDC memdc;
CDC dcMemory;
CDC *pDC;
CRect rect;

CFileDialog file(TRUE, _T("(*.bmp)|*.bmp","*.bmp" ,OFN_EXPLORER ,"位图文件(*.bmp)"));
if(!file.DoModal())
return;
GetWindowRect(rect);

filename = file.GetPathName();
HBITMAP hbitmap = (HBITMAP) LoadImage(NULL,filename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
bitmapsrc.Attach(hbitmap);
pDC = GetDC();
if(!memdc.CreateCompatibleDC(pDC))
return;
memdc.SelectObject(bitmapsrc);
pDC->StretchBlt(0,0,50,50,&memdc,100,100,50,50,SRCCOPY);
// 可以显示,但不知道如何保存
ReleaseDC(pDC);

//发贴后,有人回答,加入以下方法
HBITMAP hBitmap = CreateCompatibleBitmap(memdc.GetSafeHdc(), 50, 50);
HDC hNewDC = CreateCompatibleDC(memdc.GetSafeHdc());
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hNewDC, hBitmap);
BitBlt(hNewDC, 0, 0, 50, 50, memdc.GetSafeHdc(), 0, 0, SRCCOPY);
SelectObject(hNewDC, hOldBitmap);
bitmapdes.Attach(hOldBitmap);//保存为Cbitmap对象
SaveBitmapToFile(hOldBitmap,_T("C:\\a.bmp"));//保存为文件
//其中保存文件用(http://topic.csdn.net/t/20041206/22/3620850.html)


如何将上面pDC->StretchBlt(0,0,50,50,&memdc,100,100,50,50,SRCCOPY); 这句显示出的图像保存到Cbitmap对象和文件中?
...全文
155 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
fandh 2009-06-23
  • 打赏
  • 举报
回复
建议楼主先尝试显示出来,如果显示出来正确,应该就可以保存了!
Eleven 2009-06-23
  • 打赏
  • 举报
回复
学习
浅蓝马 2009-06-23
  • 打赏
  • 举报
回复
不好意思,有点错误。


CRect rcClient;
GetClientRect(&rcClient);

CDC* pDC = GetDC();

CDC* pMemDC = new CDC();
pMemDC->CreateCompatibleDC(pDC);

CBitmap* pMemBmp = new CBitmap();
pMemBmp->CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
pMemBmp->SelectObject(pMemBmp);

pMemDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, 0, 0, SRCCOPY);

SaveBitmapToFile(pMemBmp, _T("C:\\a.bmp"));//保存为文件

ReleaseDC(pDC);

delete pMemDC;
delete pMemBmp;
wltg2001 2009-06-23
  • 打赏
  • 举报
回复
不用写入CBitmap对象,直接利用HBITMAP来保存到BMP文件中去,下面是一段保存到BMP文件的代码:
WORD wbitsCount;//位图中每个像素所占字节数。
DWORD dwpalettelsize=0;//调色板大小
DWORD dwbmdibitsize,dwdibsize,dwwritten;
BITMAP bitmap;//定义了位图的各种的信息。
BITMAPFILEHEADER bmfhdr;//定义了大小、类型等BMP文件的信息。
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
HANDLE fh,fdib;
GetObject(hBitmap,sizeof(BITMAP),(void *)&bitmap);//得到BITMAP结构。
//以下代码是用BITMAP的信息填充BITMAPINFOHEADER结构
wbitsCount=bitmap.bmBitsPixel;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biWidth=bitmap.bmWidth;
bi.biHeight=bitmap.bmHeight;
bi.biPlanes=1;
bi.biBitCount= bitmap.bmBitsPixel ;
bi.biClrImportant=0;
bi.biClrUsed=0;
bi.biCompression=BI_RGB;
bi.biSizeImage=0;
bi.biYPelsPerMeter=0;
bi.biXPelsPerMeter=0;
//以下代码是获取调色板的长度,调色板现在的用处很少,因为256色的位图已经不多了。
if(wbitsCount<=8)
dwpalettelsize=(1<<wbitsCount)*sizeof(RGBQUAD);
//计算位图的大小,并分配相应的内存空间,注意的是没有分配BITMAPFILEHEADER。
dwbmdibitsize=((bitmap.bmWidth*wbitsCount+31)/8)*bitmap.bmHeight;
fdib=GlobalAlloc(GHND,dwbmdibitsize+dwpalettelsize+sizeof(BITMAPINFOHEADER));
lpbi=(LPBITMAPINFOHEADER)::GlobalLock(fdib);
*lpbi=bi;//将bi中的数据写入分配的内存中。
hdc=::GetDC(NULL);
GetDIBits(hdc,hBitmap,0,(UINT)bitmap.bmHeight,(LPSTR)lpbi+sizeof(BITMAPINFOHEADER)+dwpalettelsize,(BITMAPINFO *)lpbi,DIB_RGB_COLORS);
/*GetDIBits是最重要的函数,真正获得位图数据的工作就由它完成,它第一个参数为HDC,第二个参数为位图句柄,第三个参数为扫描行的开始行,一般为0,第四个为结束行,一般就是高度,第四个参数最重要,它表示接收数据的起始地址,这个地址一般是在调色板之后。第五个参数指的是接收BITMAPINFO结构的地址,这个结构上面没有写,它其实就是BITMAPINFO结构加上调色板信息。最后一个参数是格式。一般是DIB_RGB_COLORS*/
//创建文件以及文件信息头
fh=CreateFile(FileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
if(fh==INVALID_HANDLE_VALUE)
return FALSE;
bmfhdr.bfType=0x4d42;//BMP类型,一定要这样写
dwdibsize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwbmdibitsize+dwpalettelsize;//文件总长,由几个部分组成
bmfhdr.bfSize=dwdibsize;
bmfhdr.bfReserved1=0;
bmfhdr.bfReserved2=0;
bmfhdr.bfOffBits=(DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER)+dwpalettelsize;//位图数据相对于文件头的偏移量
//将文件信息头写入文件
WriteFile(fh,(LPSTR)&bmfhdr,sizeof(BITMAPFILEHEADER),&dwwritten,NULL);
//将数据写入文件,包含BITMAPINFO结构、调色板、数据
WriteFile(fh,(LPSTR)lpbi,dwdibsize,&dwwritten,NULL);
//关闭相关句柄
::GlobalUnlock(fdib);
::GlobalFree(fdib);
::CloseHandle(fh);
return TRUE;


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/wltg2001/archive/2008/04/17/2300258.aspx
浅蓝马 2009-06-23
  • 打赏
  • 举报
回复

把你的代码改造了一下。



CRect rcClient;
GetClientRect(&rcClient);

CDC* pDC = GetDC();

CDC* pMemDC = new CDC();
pMemDC->CreateCompatibleDC(pDC);

CBitmap* pMemBmp = new CBitmap();
pMemBmp->CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
pMemBmp->SelectObject(pMemBmp);

pMemDC->BitBlt(0, 0, rcClient.Width(), rcClient.Height(), pDC, 0, 0, SRCCOPY);

BitBlt(hNewDC, 0, 0, 50, 50, memdc.GetSafeHdc(), 0, 0, SRCCOPY);

SaveBitmapToFile(pMemBmp, _T("C:\\a.bmp"));//保存为文件

ReleaseDC(pDC);
fengrx 2009-06-23
  • 打赏
  • 举报
回复
HBITMAP hBitmap = CreateCompatibleBitmap(memdc.GetSafeHdc(), 50, 50);
HDC hNewDC = CreateCompatibleDC(memdc.GetSafeHdc());
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hNewDC, hBitmap);
BitBlt(hNewDC, 0, 0, 50, 50, memdc.GetSafeHdc(), 100, 100, SRCCOPY);//类似于上面的显示
SaveBitmapToFile(hBitmap,_T("C:\\a.bmp"));//保存为文件 要保存刚才创建的hbitmap
fengrx 2009-06-23
  • 打赏
  • 举报
回复
HBITMAP hBitmap = CreateCompatibleBitmap(memdc.GetSafeHdc(), 50, 50);
HDC hNewDC = CreateCompatibleDC(memdc.GetSafeHdc());
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hNewDC, hBitmap);
BitBlt(hNewDC, 0, 0, 50, 50, memdc.GetSafeHdc(), 0, 0, SRCCOPY);
SaveBitmapToFile(hBitmap,_T("C:\\a.bmp"));//保存为文件
tyzyx 2009-06-23
  • 打赏
  • 举报
回复
问题解决
tyzyx 2009-06-23
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 qlming 的回复:]

把你的代码改造了一下。


C/C++ codeCRect rcClient;
GetClientRect(&rcClient);

CDC*pDC=GetDC();

CDC*pMemDC=newCDC();
pMemDC->CreateCompatibleDC(pDC);

CBitmap*pMemBmp=newCBitmap();
pMemBmp->CreateCompatibleBitmap(pDC, rcClient.Width(), rcClient.Height());
pMemBmp->SelectObject(pMemBmp);

pMemDC->BitBlt(0,0, rcClient.Width(), rcClient.Height(), pDC,0,0, SRCCO…
[/Quote]

pMemBmp->SelectObject(pMemBmp);这句无法编译通过
bragi523 2009-06-23
  • 打赏
  • 举报
回复
没有什么补充了
greatws 2009-06-23
  • 打赏
  • 举报
回复
稍微变一下嘛。


pDC->StretchBlt(0,0,50,50,&memdc,100,100,50,50,SRCCOPY);
// 可以显示,但不知道如何保存
//ReleaseDC(pDC);

//发贴后,有人回答,加入以下方法
HBITMAP hBitmap = CreateCompatibleBitmap(pDC->GetSafeHdc(), 50, 50);
HDC hNewDC = CreateCompatibleDC(pDC->GetSafeHdc());
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hNewDC, hBitmap);
BitBlt(hNewDC, 0, 0, 50, 50, pDC->GetSafeHdc(), 0, 0, SRCCOPY);

bitmapdes.Attach(hBitmap);//保存为Cbitmap对象
SaveBitmapToFile(hBitmap, _T("C:\\a.bmp"));//保存为文件
SelectObject(hNewDC, hOldBitmap);
Ghost90 2009-06-23
  • 打赏
  • 举报
回复
把上面的代码改了下,测试了下没问题




CBitmap bitmapdes,bitmapsrc;
CString filename;
HDC m_hMemDC;
LONG m_nWidth,m_nHeight;
CDC memdc;
CDC dcMemory;
CDC *pDC;
CRect rect;

CFileDialog file(TRUE, _T("(*.bmp)|*.bmp","*.bmp" ,OFN_EXPLORER ,"位图文件(*.bmp)"));
if(!file.DoModal())
return;
GetWindowRect(rect);

filename = file.GetPathName();
HBITMAP hbitmap = (HBITMAP) LoadImage(NULL,filename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
bitmapsrc.Attach(hbitmap);
pDC = GetDC();
if(!memdc.CreateCompatibleDC(pDC))
return;
memdc.SelectObject(bitmapsrc);
pDC->StretchBlt(100,100,50,50,&memdc,30,30,50,50,SRCCOPY); //从图像的30,30位置 截大小为50,50的图像
// 可以显示,但不知道如何保存
ReleaseDC(pDC);

CRect rcClient;
GetClientRect(&rcClient);
HBITMAP hBitmap = CreateCompatibleBitmap(memdc.GetSafeHdc(),
50,50);
HDC hNewDC = CreateCompatibleDC(memdc.GetSafeHdc());
HBITMAP hOldBitmap = (HBITMAP)SelectObject(hNewDC, hBitmap);
BitBlt(hNewDC, 0, 0, 50, 50, memdc.GetSafeHdc(), 30, 30, SRCCOPY); //从图像的30,30位置 截大小为50,50的图像
SaveBitmapToFile(hBitmap,_T("e:\\a.bmp"));//保存为文件




19,468

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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