D盘

workspace
posts - 165, comments - 53, trackbacks - 0, articles - 0
  IT博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

一些不错的代码

Posted on 2008-11-17 21:33 巴西木 阅读(626) 评论(0)  编辑 收藏 引用

http://hi.baidu.com/wwl_it/blog/item/3389c5f794e99a24730eec08.html

图形学的几个非常有用的转换
2008年07月16日 星期三 18:36

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

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;
}  

只有注册用户登录后才能发表评论。