如何在两个进程间传递BMP???

sizheng0320 2007-07-04 10:17:03
进程A:实时获取摄像头得到的视频帧,可得到HBITMAP,然后通过CBitmap,可获得BITMAP。

进程B如何得到进程A获得的一个同样的BITMAP?

我想关键在于传递实际的像素信息,但是一直没有成功:(

我的做法:

进程A中:

CBitmap cb;
cb.Attach((HBITMAP)pHandle); //pHandle是一个其它类型的图片句柄
cb.GetBitmap(&(m_pFrame->image)); //m_pFrame是自定义的结构体指针,image为BITMAP cb.GetBitmapBits(800*600,&(m_pFrame->bit)); //bit为800*600大小的一维byte数组

然后通过内存共享,进程B可得到这些数据

进程B中:

myFileMapping.Read(buffer);
memcpy(frame,buffer,sizeof(FRAME));//这两行是读取A共享的数据

int x,y;
int nWidth=frame->image.bmWidth;
int nHeigh=frame->image.bmHeight;

BYTE *px = new BYTE[nHeigh*nWidth]; //声明暂存数组
for(int j=0;j<nWidth*nHeigh;j++)
px[j]=frame->bit[j];

CBitmap cb;
HBITMAP hBmp=NULL;
hBmp=::CreateBitmap(nWidth,nHeigh,frame->image.bmPlanes,frame->image.bmBitsPixel,px);
//BOOL r=cb.CreateBitmap(nWidth,nHeigh,frame->image.bmPlanes,frame->image.bmBitsPixel,px);
//cb.CreateBitmapIndirect(&(frame->image));
//DWORD r=cb.SetBitmapBits(nWidth*nHeigh,frame->bit);

但是无论是未注释掉的还是注释掉的方法,都以失败而告终,甚是郁闷

我不知道用800*600大小的数组对不对,因为我看到过这样的代码:

BYTE *bufferBmp = NULL ;
int sizeBmp = iW * iH * 4;
bufferBmp = (BYTE *)malloc(sizeof(BYTE) * sizeBmp) ;
cBitmap.GetBitmapBits(sizeBmp , bufferBmp);

这里用的是iW * iH * 4。

对图像处理不熟悉,很晕~
...全文
388 21 打赏 收藏 转发到动态 举报
写回复
用AI写文章
21 条回复
切换为时间正序
请发表友善的回复…
发表回复
sizheng0320 2007-07-06
  • 打赏
  • 举报
回复
解决了!



http://community.csdn.net/Expert/TopicView3.asp?id=5637548
eddy470 2007-07-06
  • 打赏
  • 举报
回复
共享内存不行就用管道试试看吧。
neosu 2007-07-05
  • 打赏
  • 举报
回复
lz会保存到文件不??
如果会的话, 不要把数据流写到磁盘文件, 而是用进程间通信传递, 即可。
sizheng0320 2007-07-05
  • 打赏
  • 举报
回复
晕,难道话题又转到进程通信上了?

各位说的方法我都试过了,参见

http://community.csdn.net/Expert/TopicView3.asp?id=5636334

http://community.csdn.net/Expert/TopicView3.asp?id=5637620

还是说说这个主帖的事吧,主要是关于图像处理的编程了
龙凤呈祥焱 2007-07-05
  • 打赏
  • 举报
回复
BMP数据量这么大,怎么用于实时通信啊。
HuWenjin 2007-07-05
  • 打赏
  • 举报
回复
DDE
fantiyu 2007-07-05
  • 打赏
  • 举报
回复
创建内存映射就可以了




-------------------------------------------------------
广告:VC/WinAPI 网络/多线程讨论 QQ群, 群号:41356711
oldn123 2007-07-05
  • 打赏
  • 举报
回复
dll共享数据可以
sizheng0320 2007-07-05
  • 打赏
  • 举报
回复
要实时通信,用文件效率太低,几乎锁住
qwertxp 2007-07-05
  • 打赏
  • 举报
回复
楼上说的对,存在文件里不就行了。
还可以使用DLL共享数据段。
龙凤呈祥焱 2007-07-05
  • 打赏
  • 举报
回复
直接保存到文件里不就行了。
sizheng0320 2007-07-05
  • 打赏
  • 举报
回复
而且我倒不用保存成文件,能够给进程B重现一个BITMAP就行了
sizheng0320 2007-07-05
  • 打赏
  • 举报
回复
kantonwang2007() 的办法似乎可以试试。但是 pDst 是什么?
sizheng0320 2007-07-05
  • 打赏
  • 举报
回复
不错,正是用的一个开发包,它可以对视频做人脸识别。

我们现在需要利用它得到的视频帧(已提供了函数转换成HBITMAP),来做另外的一些自己做的处理,而且更加FT的是,找到的算法是C#的,而原来视频那部分是WIN32的~也就是要把WIN32得到的HBITMAP想办法传给C#的进程处理
MLiang 2007-07-05
  • 打赏
  • 举报
回复
进程间通信
AgedBOY 2007-07-05
  • 打赏
  • 举报
回复
首先,我不知道你是怎样“实时得到摄像头视频帧”的。你怎么可能得到HBITMAP呢?这么慢的GDI对象,怎么可能用于摄像头画面呢?

1,如果你不是用DirectShow,那么建议好好看看DirectShow。在Windows平台上,处理摄像头数据,DirectShow是为数不多的几个绝对正解之一。(开源的兄弟不要出来骂人^^)而如果你使用了DirectShow,则视频帧的数据(令人垂涎的缓冲区指针)便马上抓在你自己手里了。

2,如果你是使用网上的什么衰人做的什么鸟库,从摄像头里得到图像竟然以HBITMAP输出,则建议你赶紧将鸟库删除,并且不要告诉别人你曾使用过它。

3,我个人认为你选择的File Mapping是可以实现比较快速的进程间共享数据的。一般使用640×480分辨率、YUY2或RGB24 30FPS时,File Mapping的速度应该够用了。不过这需要具体实验验证。至于楼上别的朋友说的Pipe或DLL数据段,我没有实践过不好说什么,可以自己试试。

4,楼主在解这个问题时,看起来是把“从HBITMAP里获得象素数据”当作瓶颈了,并且认为这是一个“图像处理”问题。实际上在我看来,本问题的难点应该在于如何实现高效稳定的进程间共享数据。这里,要做到高效是不容易的。而假如你一心要使用(DDB型的HBITMAP),那么就绝无可能实现高效了,并且速度慢得简直就像做梦。

总之,解楼主的问题,从摄像头获得视频帧,应该使用DirectShow,拿到象素缓冲区指针,以及拿到你想要的BITMAPINFOHEADER,简直是水到渠成的。
kantonwang2007 2007-07-05
  • 打赏
  • 举报
回复
现在实际上是如何在A取得BMP的像素数据,然后B获得像素数据后再创建相同的BMP的问题了

这个简单阿,知道画像的width, height, depth就能自己创建出来和A一样的数据的。给一个24bit的例子。
BITMAPFILEHEADER fileHead;
BITMAPINFOHEADER infoHead;

//create BITMAPINFOHEADER
infoHead.biSize = sizeof(BITMAPINFOHEADER);
infoHead.biWidth = m_nWidth;
infoHead.biHeight = m_nHeight;
infoHead.biPlanes = 1;
infoHead.biBitCount = 24;
infoHead.biCompression = BI_RGB;
infoHead.biSizeImage = m_nWidth * m_nHeight * 3;
infoHead.biXPelsPerMeter = 0;
infoHead.biYPelsPerMeter = 0;
infoHead.biClrUsed = 0;
infoHead.biClrImportant = 0;

//create BITMAPFILEHEADER
fileHead.bfType = (((int)'M') << 8) + 'B';
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
fileHead.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
fileHead.bfSize = fileHead.bfOffBits + m_nWidth * m_nHeight * 3;

*ppData = new char[fileHead.bfSize];
*pnDataSize = fileHead.bfSize;
memcpy(*ppData, (BYTE*)&fileHead, sizeof(BITMAPFILEHEADER));
memcpy(*ppData+sizeof(BITMAPFILEHEADER), (BYTE*)&infoHead, sizeof(BITMAPINFOHEADER));
memcpy(*ppData+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER), pDst, infoHead.biSizeImage);

#ifdef _DEBUG
TCHAR szFile[MAX_PATH];
memset(szFile, 0, sizeof(szFile));
swprintf(szFile, _T("c:\\[%d]decoder_%05d.bmp"), GetCurrentThreadId(), m_nFrameCount);
HANDLE hFile = ::CreateFile(szFile, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, NULL );
DWORD dwWritten = 0;
WriteFile(hFile, *ppData, *pnDataSize, &dwWritten, NULL);
CloseHandle(hFile);
#endif
home3163 2007-07-05
  • 打赏
  • 举报
回复
不太懂,期待解决,最后LZ把正确的给出来
sizheng0320 2007-07-05
  • 打赏
  • 举报
回复
其实通信的问题我已经基本解决了,至少传输简单的数据已经实现

现在的问题是,传输BMP时,只传递BITMAP和HBITMAP是不够的,因为它们里面没有BMP实际的像素数据,而是指针。

现在实际上是如何在A取得BMP的像素数据,然后B获得像素数据后再创建相同的BMP的问题了
HuWenjin 2007-07-05
  • 打赏
  • 举报
回复
做一个 DDE server
一个 DDE client

过时了,但仍然很方便
加载更多回复(1)

15,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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