OpenCV IplImage和GDI+ Bitmap的相互轉換 標籤: IplImageGDIBitmap 2013-03-28 22:00 4234人閱讀 評論(9) 收藏 舉報 分類: 映像與OpenCV(15)
IplImage和Bitmap都是記憶體配置圖形的表示方法,前者是OpenCV開源視覺庫的,後者是GDI+的。如果在VC中使用OpenCV庫的話,很可能會用到這兩者的轉換。
在網上搜尋這兩種格式轉換的話,很有可能會搜尋到有記憶體泄露的版本(比如 http://blog.csdn.net/jtujtujtu/article/details/3734722),因此在此提供了沒有記憶體泄露的版本供大家參考。
【注意】使用GDI+的FromBITMAPINFO函數會導致記憶體泄露。 [cpp] view plain copy print ? IplImage* Bitmap2IplImage(Bitmap* pBitmap) { if (!pBitmap) return NULL; int w = pBitmap->GetWidth(); int h = pBitmap->GetHeight(); BitmapData bmpData; Rect rect(0,0,w,h); pBitmap->LockBits(&rect, ImageLockModeRead, PixelFormat24bppRGB, &bmpData); BYTE* temp = (bmpData.Stride>0) ? ((BYTE*)bmpData.Scan0) : ((BYTE*)bmpData.Scan0 + bmpData.Stride*(h-1)); IplImage* pIplImg = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 3); if (!pIplImg) { pBitmap->UnlockBits(&bmpData); return NULL; } memcpy(pIplImg->imageData, temp, abs(bmpData.Stride)*bmpData.Height); pBitmap->UnlockBits(&bmpData); //判斷Top-Down or Bottom-Up if (bmpData.Stride<0) cvFlip(pIplImg, pIplImg); return pIplImg; } [cpp] view plain copy print ? // pBitmap 同樣需要外部釋放 Bitmap* IplImage2Bitmap(IplImage* pIplImg) { if(!pIplImg) return NULL; Bitmap *pBitmap = new Bitmap(pIplImg->width, pIplImg->height, PixelFormat24bppRGB); if (!pBitmap) return NULL; BitmapData bmpData; Rect rect(0, 0, pIplImg->width, pIplImg->height); pBitmap->LockBits(&rect, ImageLockModeWrite, PixelFormat24bppRGB, &bmpData); BYTE *pByte = (BYTE*)bmpData.Scan0; if (pIplImg->widthStep == bmpData.Stride) //likely memcpy(bmpData.Scan0, pIplImg->imageDataOrigin, pIplImg->imageSize);