如何在两个进程间传递BMP???
进程A:实时获取摄像头得到的视频帧,可得到HBITMAP,然后通过CBitmap,可获得BITMAP。
进程B如何得到进程A获得的一个同样的BITMAP?
我想关键在于传递实际的像素信息,但是一直没有成功:(
我的做法:
进程A中:
CBitmap cb;
cb.Attach((HBITMAP)pHandle); //pHandle是一个其它类型的图片句柄
cb.GetBitmap(&(m_pFrame-> image)); //m_pFrame是自定义的结构体指针,image为BITMAPcb.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));
//DWORDr=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。
对图像处理不熟悉,很晕~
[解决办法]
直接保存到文件里不就行了。
[解决办法]
楼上说的对,存在文件里不就行了。
还可以使用DLL共享数据段。
[解决办法]
dll共享数据可以
[解决办法]
创建内存映射就可以了
-------------------------------------------------------
广告:VC/WinAPI 网络/多线程讨论 QQ群, 群号:41356711
[解决办法]
DDE
[解决办法]
BMP数据量这么大,怎么用于实时通信啊。
[解决办法]
lz会保存到文件不??
如果会的话, 不要把数据流写到磁盘文件, 而是用进程间通信传递, 即可。
[解决办法]
以前有过类似的项目,可以生成一个bitmap文件,然后通过原子量传给另外一个进程,或者使用namepipe,直接在2个进程中进行通讯。
[解决办法]
做一个 DDE server
一个 DDE client
过时了,但仍然很方便
[解决办法]
不太懂,期待解决,最后LZ把正确的给出来
[解决办法]
现在实际上是如何在A取得BMP的像素数据,然后B获得像素数据后再创建相同的BMP的问题了
这个简单阿,知道画像的width, height, depth就能自己创建出来和A一样的数据的。给一个24bit的例子。
BITMAPFILEHEADERfileHead;
BITMAPINFOHEADERinfoHead;
//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
[解决办法]
首先,我不知道你是怎样“实时得到摄像头视频帧”的。你怎么可能得到HBITMAP呢?这么慢的GDI对象,怎么可能用于摄像头画面呢?
1,如果你不是用DirectShow,那么建议好好看看DirectShow。在Windows平台上,处理摄像头数据,DirectShow是为数不多的几个绝对正解之一。(开源的兄弟不要出来骂人^^)而如果你使用了DirectShow,则视频帧的数据(令人垂涎的缓冲区指针)便马上抓在你自己手里了。
2,如果你是使用网上的什么衰人做的什么鸟库,从摄像头里得到图像竟然以HBITMAP输出,则建议你赶紧将鸟库删除,并且不要告诉别人你曾使用过它。
3,我个人认为你选择的File Mapping是可以实现比较快速的进程间共享数据的。一般使用640×480分辨率、YUY2或RGB24 30FPS时,File Mapping的速度应该够用了。不过这需要具体实验验证。至于楼上别的朋友说的Pipe或DLL数据段,我没有实践过不好说什么,可以自己试试。
4,楼主在解这个问题时,看起来是把“从HBITMAP里获得象素数据”当作瓶颈了,并且认为这是一个“图像处理”问题。实际上在我看来,本问题的难点应该在于如何实现高效稳定的进程间共享数据。这里,要做到高效是不容易的。而假如你一心要使用—DB型的HBITMAP),那么就绝无可能实现高效了,并且速度慢得简直就像做梦。
总之,解楼主的问题,从摄像头获得视频帧,应该使用DirectShow,拿到象素缓冲区指针,以及拿到你想要的BITMAPINFOHEADER,简直是水到渠成的。
[解决办法]
进程间通信
[解决办法]
共享内存不行就用管道试试看吧。