注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

*^^* 寂寞的whitebaby

欢迎来到我的家,充满回忆的地方

 
 
 

日志

 
 
关于我

いǒDê個性伱惹吥起                 ヤ 無限囂張.習慣寂寞‰〆┈

图形学的几个非常有用的转换  

2011-03-15 16:12:57|  分类: openCV |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

1:将指定区域保存为位图信息,此区域如果从控件得到的dc而来,可以对指定控件抓图
HBITMAP CopyScreenToBitmap(LPRECT lpRect)
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap; 
// 位图句柄
int nX, nY, nX2, nY2; 
// 选定区域坐标
int nWidth, nHeight;
// 位图宽度和高度
int xScrn, yScrn; 
// 屏幕分辨率
// 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect->left;
nY = lpRect->top;
nX2 = lpRect->right;
nY2 = lpRect->bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX <0)
nX = 0;
if (nY<0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap);
//清除 
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}
2:对上面的延伸,将一个位图结构保存为文件
BOOL SaveBmp(HBITMAP hBitmap, CString FileName)
{
HDC hDC;
int iBits;
WORD wBitCount;
DWORD dwPaletteSize=0, dwBmBitsSize=0, dwDIBSize=0, dwWritten=0; 
BITMAP Bitmap; 
BITMAPFILEHEADER bmfHdr; 
BITMAPINFOHEADER bi; 
LPBITMAPINFOHEADER lpbi; 
HANDLE fh, hDib, hPal,hOldPal=NULL; 
hDC = CreateDC("DISPLAY", NULL, NULL, NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES); 
DeleteDC(hDC); 
if (iBits <= 1) wBitCount = 1; 
else if (iBits <= 4) wBitCount = 4; 
else if (iBits <= 8) wBitCount = 8; 
else wBitCount = 24; 
GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrImportant = 0;
bi.biClrUsed = 0;
dwBmBitsSize = ((Bitmap.bmWidth * wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;
hDib = GlobalAlloc(GHND,dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER)); 
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib); 
*lpbi = bi; 
hPal = GetStockObject(DEFAULT_PALETTE); 
if (hPal) 

hDC = ::GetDC(NULL); 
hOldPal = ::SelectPalette(hDC, (HPALETTE)hPal, FALSE); 
RealizePalette(hDC); 
}
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) 
+dwPaletteSize, (BITMAPINFO *)lpbi, DIB_RGB_COLORS); 
if (hOldPal) 

::SelectPalette(hDC, (HPALETTE)hOldPal, TRUE); 
RealizePalette(hDC); 
::ReleaseDC(NULL, hDC); 

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; // "BM" 
dwDIBSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + dwPaletteSize + dwBmBitsSize; 
bmfHdr.bfSize = dwDIBSize; 
bmfHdr.bfReserved1 = 0; 
bmfHdr.bfReserved2 = 0; 
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER) + dwPaletteSize;
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER), &dwWritten, NULL); 
WriteFile(fh, (LPSTR)lpbi, dwDIBSize, &dwWritten, NULL); 
GlobalUnlock(hDib); 
GlobalFree(hDib); 
CloseHandle(fh); 
return TRUE;
}
3:也是对1的延伸,将位图结构转为ipl,作为Opencv处理的接口
int stride = (width * sizeof( RGBTRIPLE ) + 3) & -4;
cvInitImageHeader( &ds_frame, cvSize(width, height), 8, 3,IPL_ORIGIN_BL, 4 );
ds_frame.widthStep = stride; 
cvSetData( &ds_frame, myBuffer, stride ); 
4:和上面的相反,将IPL转换为bitmap
IplImage* VideoResizeframe = NULL; 
CDC *pDC;
CRect rect;
BITMAPINFO bmi;
pDC = ((CPCSDlg*)AfxGetMainWnd())->m_VideoPreview.GetDC(); 
((CPCSDlg*)AfxGetMainWnd())->m_VideoPreview.GetWindowRect(rect);
VideoResizeframe = cvCreateImage(cvSize(rect.Width(), rect.Height()), IPL_DEPTH_8U,3);
cvResize(pFrame, VideoResizeframe, CV_INTER_LINEAR ); 
MYFillBitmapInfo(&bmi,VideoResizeframe->width,VideoResizeframe->height,(VideoResizeframe->depth)*(VideoResizeframe->nChannels));
::StretchDIBits(pDC->GetSafeHdc(),-4,-4,VideoResizeframe->width,VideoResizeframe->height,0,0,VideoResizeframe->width,VideoResizeframe->height,VideoResizeframe->imageData,&bmi,DIB_RGB_COLORS,SRCCOPY);
delete &bmi;
((CPCSDlg*)AfxGetMainWnd())->m_VideoPreview.ReleaseDC( pDC );
cvReleaseImage(&VideoResizeframe);
引用到的函数如下:
void MYFillBitmapInfo( BITMAPINFO* bmi, int width, int height, int bpp )
{
ASSERT( bmi && width > 0 && height > 0 &&
(bpp == 8 || bpp == 24 || bpp == 32) );
BITMAPINFOHEADER* bmih = &(bmi->bmiHeader);
memset( bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = width;
bmih->biHeight = -abs(height);
bmih->biPlanes = 1;
bmih->biBitCount = bpp;
bmih->biCompression = BI_RGB;
if( bpp == 8 )
{
RGBQUAD* palette = bmi->bmiColors;
int i;
for( i = 0; i < 256; i++ )
{
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed = (BYTE)i;
palette[i].rgbReserved = 0;
}
}
}
5:利用ipicture用接口实现vc任意控件上加载图象
HRESULT CDTS32Dlg::ShowPic(char *lpstrFile, HWND hWnd, int nScrWidth, int nScrHeight)
{
HDC hDC_Temp=(FromHandle(hWnd)->GetDC())->GetSafeHdc(); 
IPicture *pPic; 
IStream *pStm; 
BOOL bResult; 
HANDLE hFile=NULL; 
DWORD dwFileSize,dwByteRead; 
//打开硬盘中的图形文件 
hFile=CreateFile(lpstrFile,GENERIC_READ, 
FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); 
if (hFile!=INVALID_HANDLE_VALUE) 

dwFileSize=GetFileSize(hFile,NULL);//获取文件字节数 
if (dwFileSize==0xFFFFFFFF) 
return E_FAIL; 

else 

return E_FAIL; 

//分配全局存储空间 
HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); 
LPVOID pvData = NULL; 
if (hGlobal == NULL) 
return E_FAIL; 
if ((pvData = GlobalLock(hGlobal)) == NULL)//锁定分配内存块 
return E_FAIL; 
ReadFile(hFile,pvData,dwFileSize,&dwByteRead,NULL);//把文件读入内存缓冲区 
GlobalUnlock(hGlobal); 
CreateStreamOnHGlobal(hGlobal, TRUE, &pStm); 
//装入图形文件 
bResult=OleLoadPicture(pStm,dwFileSize,TRUE,IID_IPicture,(LPVOID*)&pPic); 
if(FAILED(bResult)) 
return E_FAIL; 
OLE_XSIZE_HIMETRIC hmWidth;//图片的真实宽度 
OLE_YSIZE_HIMETRIC hmHeight;//图片的真实高度 
pPic->get_Width(&hmWidth); 
pPic->get_Height(&hmHeight); 
//将图形输出到屏幕上(有点像BitBlt) 
bResult=pPic->Render(hDC_Temp,0,0,nScrWidth,nScrHeight, 
0,hmHeight,hmWidth,-hmHeight,NULL); 
pPic->Release(); 
CloseHandle(hFile);//关闭打开的文件 
if (SUCCEEDED(bResult)) 

return S_OK; 

else 

     return E_FAIL; 

}
用法:
ShowPic(lpstrFile, GetDlgItem(IDC_STATIC_LOGO)->GetSafeHwnd( ), 90, 105);

6: 对1的延伸,将位图信息保存在剪切板 
HBITMAP dest = CopyScreenToBitmap(&Rc);
if (OpenClipboard()) 

EmptyClipboard(); 
SetClipboardData(CF_BITMAP, dest); 
CloseClipboard(); 
}


IplImage* hBitmap2Ipl(HBITMAP hBmp)
{
BITMAP bmp;
::GetObject(hBmp,sizeof(BITMAP),&bmp);
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8 ;
int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
IplImage* img = cvCreateImageHeader( cvSize(bmp.bmWidth, bmp.bmHeight)
, depth, nChannels );
img->imageData =
(char*)malloc(bmp.bmHeight*bmp.bmWidth*nChannels*sizeof(char));
memcpy(img->imageData,(char*)(bmp.bmBits),bmp.bmHeight*bmp.bmWidth*nChannels);
return img;
}
void createDIB(IplImage* &pict){
IplImage * Red=cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, 1 );
IplImage * Green=cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, 1 );
IplImage * Blue=cvCreateImage( cvSize(IMAGE_WIDTH,IMAGE_HEIGHT),
IPL_DEPTH_8U, 1 );
cvSetImageCOI( pict, 3);
cvCopy(pict,Red);
cvSetImageCOI( pict, 2);
cvCopy(pict,Green);
cvSetImageCOI(pict, 1);
cvCopy(pict,Blue);
//Initialize the BMP display buffer
bmi = (BITMAPINFO*)buffer;
bmih = &(bmi->bmiHeader);
memset( bmih, 0, sizeof(*bmih));
bmih->biSize = sizeof(BITMAPINFOHEADER);
bmih->biWidth = IMAGE_WIDTH;
bmih->biHeight = IMAGE_HEIGHT; // -IMAGE_HEIGHT;
bmih->biPlanes = 1;
bmih->biCompression = BI_RGB;
bmih->biBitCount = 24;
palette = bmi->bmiColors;
for( int i = 0; i < 256; i++ ){
palette[i].rgbBlue = palette[i].rgbGreen = palette[i].rgbRed =
(BYTE)i;
palette[i].rgbReserved = 0;
}
cvReleaseImage(&Red);
cvReleaseImage(&Green);
cvReleaseImage(&Blue);
}

IplImage* hBitmap2Ipl(HBITMAP hBmp)
{
BITMAP bmp; 
::GetObject(hBmp,sizeof(BITMAP),&bmp);
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8 ;
int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U;
CString t;
t.Format("%d %d %d %d",bmp.bmWidth,bmp.bmHeight,depth,nChannels);
AfxMessageBox(t);
IplImage* img = cvCreateImage(cvSize(bmp.bmWidth,bmp.bmHeight),depth,nChannels); //cvCreateImageHeader
//img->origin = 1;
//img->widthStep = (bmp.bmWidth * sizeof( RGBTRIPLE ) + 3) & -4;
BYTE *pBuffer = new BYTE[bmp.bmHeight*bmp.bmWidth*nChannels]; 
GetBitmapBits(hBmp,bmp.bmHeight*bmp.bmWidth*nChannels,pBuffer); 
//cvSetData(img,(BYTE*)(bmp.bmBits),img->widthStep);
//cvSetData(img,pBuffer,bmp.bmHeight*bmp.bmWidth*nChannels);
memcpy(img->imageData,pBuffer,bmp.bmHeight*bmp.bmWidth*nChannels);
/* IplImage* img = cvCreateImageHeader(cvSize(bmp.bmWidth,bmp.bmHeight),depth,nChannels);
img->imageData = (char*)malloc(bmp.bmHeight*bmp.bmWidth*nChannels*sizeof(char)); 
memcpy(img->imageData,(char*)(bmp.bmBits),bmp.bmHeight*bmp.bmWidth*nChannels);
*/ 
return img;
}

IplImage* hBitmap2Ipl(HBITMAP hBmp)
{
BITMAP bmp; 
::GetObject(hBmp,sizeof(BITMAP),&bmp); 
int nChannels = bmp.bmBitsPixel == 1 ? 1 : bmp.bmBitsPixel/8 ;
int depth = bmp.bmBitsPixel == 1 ? IPL_DEPTH_1U : IPL_DEPTH_8U; 
IplImage* img = cvCreateImage(cvSize(bmp.bmWidth,bmp.bmHeight),depth,nChannels); //cvCreateImageHeader
BYTE *pBuffer = new BYTE[bmp.bmHeight*bmp.bmWidth*nChannels]; 
GetBitmapBits(hBmp,bmp.bmHeight*bmp.bmWidth*nChannels,pBuffer); 
memcpy(img->imageData,pBuffer,bmp.bmHeight*bmp.bmWidth*nChannels);
delete pBuffer; 
return img;
}  

  评论这张
 
阅读(646)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018