VMR_Capture.cpp
资源名称:VideoMove.rar [点击查看]
上传用户:czshopping
上传日期:2022-05-22
资源大小:5430k
文件大小:19k
源码类别:
视频捕捉/采集
开发平台:
Visual C++
- //////////////////////////////////////////////////////////////////////
- //
- // This class is designed to provide simple interface for
- // simultaneous Video Capture & Preview using DirectShow
- //
- //////////////////////////////////////////////////////////////////////
- //
- // References: MS DirectShow Samples
- //
- //
- //////////////////////////////////////////////////////////////////////
- //
- // This class was written by Sagar K.R .
- // Use of this class is not restricted in any
- // way whatsoever.Please report the bugs to krssagar@firsteccom.co.kr
- //
- // Special thanks to all the members at The Code Project!
- // (www.codeproject.com)
- //
- //////////////////////////////////////////////////////////////////////
- // VMR_Capture.cpp: implementation of the CVMR_Capture class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "VMR_Capture.h"
- #define SAFE_RELEASE(x) { if (x) x->Release(); x = NULL; }
- int iMinOld=0,iMinNew=0;
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CVMR_Capture::CVMR_Capture()
- {
- CoInitialize(NULL);
- m_pGB = NULL;
- m_pMC = NULL;
- m_pME = NULL;
- m_pWC = NULL;
- m_pDF =NULL;
- m_pCamOutPin =NULL;
- m_pFrame=NULL;
- m_nFramelen=0;
- m_psCurrent=Stopped;
- m_iHeight=240;
- m_iWidth=320;
- lpVideo=this;
- }
- CVMR_Capture::~CVMR_Capture()
- {
- CloseInterfaces();
- CoUninitialize( );
- m_MoveTrace.Uninitialize();
- }
- HRESULT CVMR_Capture::Init(int iDeviceID,HWND hWnd, int iWidth, int iHeight)
- {
- HRESULT hr;
- // Get the interface for DirectShow's GraphBuilder
- hr=CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
- IID_IGraphBuilder, (void **)&m_pGB);
- if(SUCCEEDED(hr))
- {
- // Create the Video Mixing Renderer and add it to the graph
- InitializeWindowlessVMR(hWnd);
- // Bind Device Filter. We know the device because the id was passed in
- if(!BindFilter(iDeviceID, &m_pDF))
- return S_FALSE;
- hr=m_pGB->AddFilter(m_pDF, L"Video Capture");
- if (FAILED(hr))
- return hr;
- CComPtr<IEnumPins> pEnum;
- m_pDF->EnumPins(&pEnum);
- hr = pEnum->Reset();
- hr = pEnum->Next(1, &m_pCamOutPin, NULL);
- // QueryInterface for DirectShow interfaces
- hr = m_pGB->QueryInterface(IID_IMediaControl, (void **)&m_pMC);
- hr = m_pGB->QueryInterface(IID_IMediaEventEx, (void **)&m_pME);
- // Have the graph signal event via window callbacks for performance
- //hr = pME->SetNotifyWindow((OAHWND)hWnd, WM_GRAPHNOTIFY, 0);
- hr = InitVideoWindow(hWnd,iWidth, iHeight);
- m_nFramelen=iWidth*iHeight*3;
- m_pFrame=(BYTE*) new BYTE[m_nFramelen];
- // Run the graph to play the media file
- m_psCurrent=Stopped;
- hr = m_pGB->Render(m_pCamOutPin);
- hr = m_pMC->Run();
- m_psCurrent=Running;
- }
- // m_hCapWnd=hWnd;
- ///////////////////////////////////////
- m_hParentWnd=hWnd;
- m_hCapWnd=hWnd;
- // m_hCapWnd= capCreateCaptureWindow(
- // (LPSTR)"Face Video Capture Window", WS_CHILD|WS_VISIBLE,
- // 0, 0,m_iWidth,m_iHeight,
- // hwndParent, nCapWndID );
- m_pDC=CWnd::FromHandle(m_hParentWnd)->GetDC();
- if (m_MemDC.GetSafeHdc()==NULL)
- {
- m_MemDC.CreateCompatibleDC(m_pDC);
- }
- m_Bitmap.CreateCompatibleBitmap(m_pDC,m_iWidth,m_iHeight);
- m_MoveTrace.Initialize(320, 240,3,3);
- m_bStorageData=FALSE;
- //////////////////////////////////////
- return hr;
- }
- HRESULT CVMR_Capture::InitializeWindowlessVMR(HWND hWnd)
- {
- IBaseFilter* pVmr = NULL;
- // Create the VMR and add it to the filter graph.
- HRESULT hr = CoCreateInstance(CLSID_VideoMixingRenderer, NULL,
- CLSCTX_INPROC, IID_IBaseFilter, (void**)&pVmr);
- if (SUCCEEDED(hr))
- {
- hr = m_pGB->AddFilter(pVmr, L"Video Mixing Renderer");
- if (SUCCEEDED(hr))
- {
- // Set the rendering mode and number of streams.
- IVMRFilterConfig* pConfig;
- hr = pVmr->QueryInterface(IID_IVMRFilterConfig, (void**)&pConfig);
- if( SUCCEEDED(hr))
- {
- pConfig->SetRenderingMode(VMRMode_Windowless);
- pConfig->Release();
- }
- hr = pVmr->QueryInterface(IID_IVMRWindowlessControl, (void**)&m_pWC);
- if( SUCCEEDED(hr))
- {
- m_pWC->SetVideoClippingWindow(hWnd);
- }
- }
- pVmr->Release();
- }
- return hr;
- }
- bool CVMR_Capture::BindFilter(int deviceId, IBaseFilter **pFilter)
- {
- if (deviceId < 0)
- return false;
- // enumerate all video capture devices
- CComPtr<ICreateDevEnum> pCreateDevEnum;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum, (void**)&pCreateDevEnum);
- if (hr != NOERROR)
- {
- return false;
- }
- CComPtr<IEnumMoniker> pEm;
- hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
- &pEm, 0);
- if (hr != NOERROR)
- {
- return false;
- }
- pEm->Reset();
- ULONG cFetched;
- IMoniker *pM;
- int index = 0;
- while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK, index <= deviceId)
- {
- IPropertyBag *pBag;
- hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
- if(SUCCEEDED(hr))
- {
- VARIANT var;
- var.vt = VT_BSTR;
- hr = pBag->Read(L"FriendlyName", &var, NULL);
- if (hr == NOERROR)
- {
- if (index == deviceId)
- {
- pM->BindToObject(0, 0, IID_IBaseFilter, (void**)pFilter);
- }
- SysFreeString(var.bstrVal);
- }
- pBag->Release();
- }
- pM->Release();
- index++;
- }
- return true;
- }
- HRESULT CVMR_Capture::InitVideoWindow(HWND hWnd,int width, int height)
- {
- // Set the grabbing size
- // First we iterate through the available media types and
- // store the first one that fits the requested size.
- // If we have found one, we set it.
- // In any case we query the size of the current media type
- // to have this information for clients of this class.
- // Gerhard Reitmayr <reitmayr@i ...............>
- HRESULT hr;
- RECT rcDest;
- CComPtr<IAMStreamConfig> pConfig;
- IEnumMediaTypes *pMedia;
- AM_MEDIA_TYPE *pmt = NULL, *pfnt = NULL;
- hr = m_pCamOutPin->EnumMediaTypes( &pMedia );
- if(SUCCEEDED(hr))
- {
- while(pMedia->Next(1, &pmt, 0) == S_OK)
- {
- if( pmt->formattype == FORMAT_VideoInfo )
- {
- VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pmt->pbFormat;
- // printf("Size %i %in", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight );
- if( vih->bmiHeader.biWidth == width && vih->bmiHeader.biHeight == height )
- {
- pfnt = pmt;
- // printf("found mediatype with %i %in", vih->bmiHeader.biWidth, vih->bmiHeader.biHeight );
- //char test[100];
- //sprintf(test,"Width=%dnHeight=%d",vih->bmiHeader.biWidth, vih->bmiHeader.biHeight);
- //MessageBox(test);
- break;
- }
- DeleteMediaType( pmt );
- }
- }
- pMedia->Release();
- }
- hr = m_pCamOutPin->QueryInterface( IID_IAMStreamConfig, (void **) &pConfig );
- if(SUCCEEDED(hr))
- {
- if( pfnt != NULL )
- {
- hr=pConfig->SetFormat( pfnt );
- //if(SUCCEEDED(hr))
- //MessageBox("OK");
- DeleteMediaType( pfnt );
- }
- hr = pConfig->GetFormat( &pfnt );
- if(SUCCEEDED(hr))
- {
- m_nWidth = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biWidth;
- m_nHeight = ((VIDEOINFOHEADER *)pfnt->pbFormat)->bmiHeader.biHeight;
- DeleteMediaType( pfnt );
- }
- }
- ::GetClientRect (hWnd,&rcDest);
- hr = m_pWC->SetVideoPosition(NULL, &rcDest);
- return hr;
- }
- void CVMR_Capture::StopCapture()
- {
- HRESULT hr;
- if((m_psCurrent == Paused) || (m_psCurrent == Running))
- {
- LONGLONG pos = 0;
- hr = m_pMC->Stop();
- m_psCurrent = Stopped;
- // Display the first frame to indicate the reset condition
- hr = m_pMC->Pause();
- }
- // CWnd::FromHandle(m_hParentWnd)->ReleaseDC(m_pDC);
- m_Bitmap.DeleteObject();
- if (m_MemDC.GetSafeHdc()!=NULL)
- {
- m_MemDC.DeleteDC();
- }
- }
- void CVMR_Capture::CloseInterfaces(void)
- {
- HRESULT hr;
- // Stop media playback
- if(m_pMC)
- hr = m_pMC->Stop();
- m_psCurrent = Stopped;
- // Disable event callbacks
- /*
- if (pME)
- hr = m_pME->SetNotifyWindow((OAHWND)NULL, 0, 0);
- */
- // SAFE_RELEASE(pME);
- // Release and zero DirectShow interfaces
- if(m_pCamOutPin)
- m_pCamOutPin->Disconnect ();
- SAFE_RELEASE(m_pCamOutPin);
- SAFE_RELEASE(m_pMC);
- SAFE_RELEASE(m_pGB);
- SAFE_RELEASE(m_pWC);
- SAFE_RELEASE(m_pDF);
- //delete allocated memory
- if(m_pFrame!=NULL)
- delete []m_pFrame;
- }
- //Capture RAW IMAGE BITS 24bits/pixel
- DWORD CVMR_Capture::ImageCapture(LPCTSTR szFile)
- {
- BYTE *pImage;
- DWORD dwSize,dwWritten;
- dwSize=this->GrabFrame ();
- this->GetFrame (&pImage);
- HANDLE hFile = CreateFile(szFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
- CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
- if (hFile == INVALID_HANDLE_VALUE)
- return FALSE;
- WriteFile(hFile, (LPCVOID)pImage , m_nFramelen, &dwWritten, 0);
- // Close the file
- CloseHandle(hFile);
- return dwWritten;
- }
- void CVMR_Capture::DeleteMediaType(AM_MEDIA_TYPE *pmt)
- {
- // allow NULL pointers for coding simplicity
- if (pmt == NULL) {
- return;
- }
- if (pmt->cbFormat != 0) {
- CoTaskMemFree((PVOID)pmt->pbFormat);
- // Strictly unnecessary but tidier
- pmt->cbFormat = 0;
- pmt->pbFormat = NULL;
- }
- if (pmt->pUnk != NULL) {
- pmt->pUnk->Release();
- pmt->pUnk = NULL;
- }
- CoTaskMemFree((PVOID)pmt);
- }
- DWORD CVMR_Capture::GrabFrame()
- {
- long lOut=-1;
- if(m_pWC )
- {
- BYTE* lpCurrImage = NULL;
- // Read the current video frame into a byte buffer. The information
- // will be returned in a packed Windows DIB and will be allocated
- // by the VMR.
- if(m_pWC->GetCurrentImage(&lpCurrImage) == S_OK)
- {
- LPBITMAPINFOHEADER pdib = (LPBITMAPINFOHEADER) lpCurrImage;
- if(m_pFrame==NULL || (pdib->biHeight * pdib->biWidth * 3) !=m_nFramelen )
- {
- if(m_pFrame!=NULL)
- delete []m_pFrame;
- m_nFramelen=pdib->biHeight * pdib->biWidth * 3;
- m_pFrame=new BYTE [pdib->biHeight * pdib->biWidth * 3] ;
- }
- if(pdib->biBitCount ==32)
- {
- DWORD dwSize=0, dwWritten=0;
- BYTE *pTemp32;
- pTemp32=lpCurrImage + sizeof(BITMAPINFOHEADER);
- //change from 32 to 24 bit /pixel
- this->Convert24Image(pTemp32, m_pFrame, pdib->biSizeImage);
- }
- CoTaskMemFree(lpCurrImage); //free the image
- }
- else
- {
- return lOut;
- }
- }
- else
- {
- return lOut;
- }
- return lOut=m_nFramelen;
- }
- bool CVMR_Capture::Convert24Image(BYTE *p32Img, BYTE *p24Img,DWORD dwSize32)
- {
- if(p32Img != NULL && p24Img != NULL && dwSize32>0)
- {
- DWORD dwSize24;
- dwSize24=(dwSize32 * 3)/4;
- BYTE *pTemp,*ptr;
- //pTemp=p32Img + sizeof(BITMAPINFOHEADER); ;
- pTemp=p32Img;
- ptr=p24Img + dwSize24-1 ;
- int ival=0;
- for (DWORD index = 0; index < dwSize32/4 ; index++)
- {
- unsigned char r = *(pTemp++);
- unsigned char g = *(pTemp++);
- unsigned char b = *(pTemp++);
- (pTemp++);//skip alpha
- *(ptr--) = b;
- *(ptr--) = g;
- *(ptr--) = r;
- }
- }
- else
- {
- return false;
- }
- return true;
- }
- BOOL CVMR_Capture::Pause()
- {
- if (!m_pMC)
- return FALSE;
- if(((m_psCurrent == Paused) || (m_psCurrent == Stopped)) )
- {
- this->StopCapture();
- if (SUCCEEDED(m_pMC->Run()))
- m_psCurrent = Running;
- }
- else
- {
- if (SUCCEEDED(m_pMC->Pause()))
- m_psCurrent = Paused;
- }
- return TRUE;
- }
- DWORD CVMR_Capture::GetFrame(BYTE **pFrame)
- {
- if(m_pFrame && m_nFramelen)
- {
- *pFrame=m_pFrame;
- }
- return m_nFramelen;
- }
- int CVMR_Capture::EnumDevices(HWND hList)
- {
- if (!hList)
- return -1;
- int id = 0;
- // enumerate all video capture devices
- CComPtr<ICreateDevEnum> pCreateDevEnum;
- // ICreateDevEnum *pCreateDevEnum;
- HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, NULL, CLSCTX_INPROC_SERVER,
- IID_ICreateDevEnum, (void**)&pCreateDevEnum);
- if (hr != NOERROR)
- {
- return -1;
- }
- CComPtr<IEnumMoniker> pEm;
- hr = pCreateDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory,
- &pEm, 0);
- if (hr != NOERROR)
- {
- return -1 ;
- }
- pEm->Reset();
- ULONG cFetched;
- IMoniker *pM;
- while(hr = pEm->Next(1, &pM, &cFetched), hr==S_OK)
- {
- IPropertyBag *pBag;
- hr = pM->BindToStorage(0, 0, IID_IPropertyBag, (void **)&pBag);
- if(SUCCEEDED(hr))
- {
- VARIANT var;
- var.vt = VT_BSTR;
- hr = pBag->Read(L"FriendlyName", &var, NULL);
- if (hr == NOERROR)
- {
- TCHAR str[2048];
- id++;
- WideCharToMultiByte(CP_ACP,0,var.bstrVal, -1, str, 2048, NULL, NULL);
- (long)SendMessage(hList, CB_ADDSTRING, 0,(LPARAM)str);
- SysFreeString(var.bstrVal);
- }
- pBag->Release();
- }
- pM->Release();
- }
- return id;
- }
- typedef struct{
- int lui;
- int luj;
- int h;
- int w;
- }AREA;
- typedef struct{
- int upx;
- int upy;
- int width;
- int height;
- AREA leftEyeArea;
- AREA rightEyeArea;
- AREA leftPupil;
- AREA rightPupil;
- AREA noseArea;
- AREA mouthArea;
- }FACE_LOCATION;
- /*
- BOOL UsedFuction(unsigned char * pImage, int Width, int Height,
- FACE_LOCATION * face, int * FaceNumber);
- HINSTANCE Dll_handler;
- typedef BOOL(DLLTEST)(BYTE* pData, int w, int h, int* FaceLeftUpX, int*
- FaceLeftUpY,
- int* FaceRightDownX, int* FaceRightDownY, int* FaceNumber);
- DLLTEST* DllTest;
- Dll_handler =
- LoadLibrary("F:\最新文档2006年12月\newdll\Release\newdll");
- DllTest=(DLLTEST*)GetProcAddress(Dll_handler,"fuction_1");
- iReturn1=(*DllTest)(pData, w, h, FaceLeftUpX,FaceLeftUpY,
- FaceRightDownX,FaceRightDownY, &FaceNumber);
- if (!nRet){ TRACE("Failed to detect face.rn");
- delete pImg;
- continue;
- }
- FreeLibrary(Dll_handler);
- Dll_handler=NULL;
- */
- BOOL CVMR_Capture::Trace(BYTE *pImageByte)
- {
- ////////////////////////////////////////////////////////////////////////
- // MoveWindow(100,100,320,240);
- /////////////////////////////////////
- if (lpVideo == NULL)
- return (LRESULT) TRUE;
- //////////////////////////////////
- unsigned char* pImgData;
- pImgData=pImageByte;
- int x, y, nX, nY;
- nX = 1;
- nY = 1;
- const int nMosaicWidth=4;
- const int nMosaicHeight=4;
- CBitmap *pOldBitmap;
- pOldBitmap=lpVideo->m_MemDC.SelectObject(&lpVideo->m_Bitmap);
- lpVideo->m_MoveTrace.GetDIBBit(pImgData);//lpVHdr->lpData
- lpVideo->m_MoveTrace.Extract(nX, nY);
- lpVideo->m_MoveTrace.Grey(); //m_Grey1
- lpVideo->m_MoveTrace.Sobel(); //m_Grey1
- int nThreshold=lpVideo->m_MoveTrace.GetThreshold(30);// ThresholdDIB((LPSTR)lpVideo->m_MoveTrace.m_pGrey1,320,240);
- lpVideo->m_MoveTrace.FrameMinus(); //m_pGrey[x]=abs(m_pGrey1[x] - m_pGrey2[x]);
- lpVideo->m_MoveTrace.Mosaic(nMosaicWidth, nMosaicHeight); //m_pGrey --> m_pMosaic
- lpVideo->m_MoveTrace.Dither(nThreshold); //m_pMosaic
- for( y=0;y<lpVideo->m_iHeight;y+=1)
- {
- for( x=0;x<lpVideo->m_iWidth;x+=1)
- {
- int nPos = y/nY*lpVideo->m_iWidth/nX+x/nX;
- int nTemp = lpVideo->m_MoveTrace.m_pMosaic[nPos];
- // int nTemp = lpVideo->m_MoveTrace.m_pGrey[nPos];
- // int nTemp = lpVideo->m_MoveTrace.m_pGrey1[nPos];
- lpVideo->m_MemDC.SetPixel(x,lpVideo->m_iHeight-1-y,RGB(nTemp,nTemp,nTemp));
- }
- }
- lpVideo->m_MoveTrace.SaveFrame(); //m_pGrey2[x] = m_pGrey1[x];
- CRect rect;
- bool bRet1=lpVideo->m_MoveTrace.Rectangle(rect,100,5);//m_pMosaic
- if (bRet1)
- {
- lpVideo->m_MemDC.Draw3dRect(&rect, RGB(0, 255, 0), RGB(0, 255, 0));
- lpVideo->m_MemDC.Draw3dRect(&lpVideo->m_MoveTrace.m_NextRect, RGB(0, 0, 255), RGB(0, 0, 255));
- lpVideo->m_MemDC.Draw3dRect(&lpVideo->m_MoveTrace.m_CurrentRect, RGB(255, 0, 0), RGB(255, 0, 0));
- }
- //SetDIBitsToDevice(lpVideo->m_pDC->m_hDC,0,0,m_iWidth,m_iHeight,0,0,);
- BOOL bRet=lpVideo->m_pDC->BitBlt(
- 250,0,
- lpVideo->m_iWidth,
- lpVideo->m_iHeight,
- &lpVideo->m_MemDC,
- 0,0,
- SRCCOPY);
- lpVideo->m_MemDC.SelectObject(pOldBitmap);
- //保存图片
- CTime Time=CTime::GetCurrentTime();
- CString strTime = Time.Format("%H%M%S");
- iMinNew=Time.GetMinute( );
- strTime="pics\"+strTime;
- if((iMinNew-iMinOld)>1)m_bStorageData=TRUE;
- if(lpVideo->m_bStorageData)
- {
- // lpVideo->SaveImage(lpVHdr);
- lpVideo->WriteAsBMP(strTime.GetBuffer(strTime.GetLength()),pImgData,320,240);
- lpVideo->m_bStorageData = FALSE;
- iMinOld=iMinNew;
- }
- return true;
- ////////////////////////////////////////////////////////////////////////
- }
- void CVMR_Capture::MoveWindow(int x,int y,int nWidth,int nHeight)
- {
- //m_iWidth = nWidth;
- //m_iHeight = nHeight;
- ::MoveWindow(m_hCapWnd,x,y,nWidth,nHeight,TRUE);
- }
- /////////////////////////////////////////////////////////////////////////////////
- BOOL CVMR_Capture::WriteAsBMP(char* szFileName,unsigned char* pImgData,int nWidth,int nHeight)
- {
- char aFileName[255];
- int nStrLen;
- if(strstr(szFileName,".")==NULL)
- {
- strcpy(aFileName,szFileName);
- strcat(aFileName,".bmp");
- }
- else
- {
- nStrLen=strlen(szFileName)-strlen(strstr(szFileName,"."));
- strncpy(aFileName,szFileName,nStrLen);
- aFileName[nStrLen]=' ';
- strcat(aFileName,".bmp");
- }
- BITMAPFILEHEADER bmfHdr; // Header for Bitmap file
- /* Fill in file type (first 2 bytes must be "BM" for a bitmap) */
- bmfHdr.bfType = 0x4d42; // "BM"
- // Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
- int nImgWidth;
- if (nWidth%4==0)
- {
- nImgWidth=nWidth*3;
- }
- else
- {
- nImgWidth=nWidth*3+nWidth%4;
- }
- bmfHdr.bfSize =(DWORD)( nImgWidth*nHeight + sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER) );
- bmfHdr.bfReserved1 = 0;
- bmfHdr.bfReserved2 = 0;
- bmfHdr.bfOffBits = (DWORD)(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
- BITMAPINFOHEADER BMIH; // Pointer to DIB info structure
- BMIH.biSize=sizeof(BITMAPINFOHEADER);
- BMIH.biHeight=nHeight;
- BMIH.biWidth=nWidth;
- BMIH.biPlanes=1;
- BMIH.biBitCount=24;
- BMIH.biCompression=BI_RGB;
- BMIH.biSizeImage=nImgWidth*nHeight;
- BMIH.biXPelsPerMeter=0xec4;
- BMIH.biYPelsPerMeter =0xec4;
- BMIH.biClrUsed =0;
- BMIH.biClrImportant=0;
- FILE *pFile;
- pFile=fopen(aFileName,"wb");
- if (pFile==NULL)
- {
- return FALSE;
- }
- BYTE aTemp[12]={0};
- try {
- // Write the file header
- fwrite((BYTE*)&bmfHdr,1,sizeof(BITMAPFILEHEADER),pFile);
- // Write the DIB header
- fwrite((BYTE*)&BMIH,1,sizeof(BITMAPINFOHEADER),pFile);
- // Write the DIB bits
- int j;
- for (j=0;j<nHeight;j++)
- {
- int i;
- i=nHeight-j;
- fwrite(pImgData+i*nWidth*3,1,nWidth*3,pFile);
- fwrite(aTemp,1,nWidth%4,pFile);
- }
- }
- catch(...)
- {
- fclose(pFile);
- return FALSE;
- }
- fclose(pFile);
- return TRUE;
- }