/**************************************************************************** * * WRITEAVI.C Modified 2003 * * Creates the file OUTPUT.AVI, an AVI file consisting of a rotating clock * face. This program demonstrates using the functions in AVIFILE.DLL * to make writing AVI files simple. * * This is a stripped-down example; a real application would have a user * interface and check for errors. * ***************************************************************************/ #include "stdafx.h" #include #include #include #include #include "writeavi.h" CAVIFile::CAVIFile() : m_bHasSaveOptionsDialog(TRUE), m_nColorNum(8)//256色 { m_pfile = NULL; m_ps = NULL; m_psCompressed = NULL; m_psText = NULL; m_pOpts[0] = &m_opts; WORD wVer = HIWORD(VideoForWindowsVersion()); if (wVer < 0x010A) { // oops, we are too old, blow out of here m_bOK = FALSE; } else { AVIFileInit(); } m_hSaveOptionsParentWnd = NULL; } CAVIFile::CAVIFile(LPCTSTR lpszFileName, int xdim, int ydim, int rate) : m_sFileName(lpszFileName), m_nXDim(xdim), m_nYDim(ydim), m_bOK(TRUE), m_nFrame(0), m_nRate(rate), m_bHasSaveOptionsDialog(TRUE), m_nColorNum(8)//256色 { m_pfile = NULL; m_ps = NULL; m_psCompressed = NULL; m_psText = NULL; m_pOpts[0] = &m_opts; WORD wVer = HIWORD(VideoForWindowsVersion()); if (wVer < 0x010A) { // oops, we are too old, blow out of here m_bOK = FALSE; } else { AVIFileInit(); } } CAVIFile::~CAVIFile() { if (m_ps) AVIStreamClose(m_ps); if (m_psCompressed) AVIStreamClose(m_psCompressed); if (m_psText) AVIStreamClose(m_psText); if (m_pfile) AVIFileClose(m_pfile); WORD wVer = HIWORD(VideoForWindowsVersion()); if (wVer >= 0x010A) { AVIFileExit(); } } void CAVIFile::Init(LPCTSTR lpszFileName, int xdim, int ydim, int rate) { m_sFileName = lpszFileName; m_nXDim = xdim; m_nYDim = ydim; m_bOK = TRUE; m_nFrame = 0; m_nRate = rate; } BOOL CAVIFile::Compress() { HRESULT hr; hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &m_opts, NULL); if (hr != AVIERR_OK) return FALSE; AVIFileRelease(m_pfile); return TRUE; } HANDLE CAVIFile::MakeDib( HBITMAP hbitmap, UINT bits ) { HANDLE hdib ; HDC hdc ; BITMAP bitmap ; UINT wLineLen ; DWORD dwSize ; DWORD wColSize ; LPBITMAPINFOHEADER lpbi ; LPBYTE lpBits ; GetObject(hbitmap,sizeof(BITMAP),&bitmap) ; // // DWORD align the width of the DIB // Figure out the size of the colour table // Calculate the size of the DIB // wLineLen = (bitmap.bmWidth*bits+31)/32 * 4; wColSize = sizeof(RGBQUAD)*((bits <= 8) ? 1<biSize = sizeof(BITMAPINFOHEADER) ; lpbi->biWidth = bitmap.bmWidth ; lpbi->biHeight = bitmap.bmHeight ; lpbi->biPlanes = 1 ; lpbi->biBitCount = (WORD) bits ; lpbi->biCompression = BI_RGB ; lpbi->biSizeImage = dwSize - sizeof(BITMAPINFOHEADER) - wColSize ; lpbi->biXPelsPerMeter = 0 ; lpbi->biYPelsPerMeter = 0 ; lpbi->biClrUsed = (bits <= 8) ? 1<biClrImportant = 0 ; // // Get the bits from the bitmap and stuff them after the LPBI // lpBits = (LPBYTE)(lpbi+1)+wColSize ; hdc = CreateCompatibleDC(NULL) ; GetDIBits(hdc,hbitmap,0,bitmap.bmHeight,lpBits,(LPBITMAPINFO)lpbi, DIB_RGB_COLORS); // Fix this if GetDIBits messed it up.... lpbi->biClrUsed = (bits <= 8) ? 1<biWidth; int nYDim = alpbi->biHeight; if (m_nXDim>=0 && m_nXDim != nXDim) { GlobalFreePtr(alpbi); return FALSE; } if (m_nYDim>=0 && m_nYDim != nYDim) { GlobalFreePtr(alpbi); return FALSE; } m_nXDim = nXDim; m_nYDim = nYDim; if (m_nFrame == 0) { hr = AVIFileOpen(&m_pfile, // returned file pointer m_sFileName, // file name OF_WRITE | OF_CREATE, // mode to open file with NULL); // use handler determined // from file extension.... if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } _fmemset(&m_strhdr, 0, sizeof(m_strhdr)); m_strhdr.fccType = streamtypeVIDEO; // stream type m_strhdr.fccHandler = 0; m_strhdr.dwScale = 1; m_strhdr.dwRate = m_nRate; // 80 fps avi rate m_strhdr.dwSuggestedBufferSize = alpbi->biSizeImage; SetRect(&m_strhdr.rcFrame, 0, 0, // rectangle for stream m_nXDim,m_nYDim); // And create the stream; hr = AVIFileCreateStream(m_pfile, // file pointer &m_ps, // returned stream pointer &m_strhdr); // stream header if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } _fmemset(&m_opts, 0, sizeof(m_opts)); //是否屏蔽掉属性对话框 if (m_bHasSaveOptionsDialog) { if (!AVISaveOptions(m_hSaveOptionsParentWnd,0,1, &m_ps,(LPAVICOMPRESSOPTIONS FAR *)&m_pOpts)) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } } hr = AVIMakeCompressedStream(&m_psCompressed, m_ps, &m_opts, NULL); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } hr = AVIStreamSetFormat(m_psCompressed, 0, alpbi, // stream format alpbi->biSize + // format size alpbi->biClrUsed * sizeof(RGBQUAD)); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } // Fill in the stream header for the text stream.... // The text stream is in 60ths of a second.... /*_fmemset(&m_strhdr, 0, sizeof(m_strhdr)); m_strhdr.fccType = streamtypeTEXT; m_strhdr.fccHandler = mmioFOURCC('D', 'R', 'A', 'W'); m_strhdr.dwScale = 1; m_strhdr.dwRate = 60; m_strhdr.dwSuggestedBufferSize = sizeof(m_szText); SetRect(&m_strhdr.rcFrame, 0, (int) alpbi->biHeight, (int) alpbi->biWidth, (int) alpbi->biHeight + TEXT_HEIGHT); // ....and create the stream. hr = AVIFileCreateStream(m_pfile, &m_psText, &m_strhdr); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } m_dwTextFormat = sizeof(m_dwTextFormat); hr = AVIStreamSetFormat(m_psText, 0, &m_dwTextFormat, sizeof(m_dwTextFormat)); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; }*/ } // Jetzt eigentliches Schreiben hr = AVIStreamWrite(m_psCompressed, // stream pointer m_nFrame * 10, //10, // time of this frame 1, // number to write (LPBYTE) alpbi + // pointer to data alpbi->biSize + alpbi->biClrUsed * sizeof(RGBQUAD), alpbi->biSizeImage, // size of this frame AVIIF_KEYFRAME, // flags.... NULL, NULL); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } // Make some text to put in the file ... //LoadString(hInstance, IDS_TEXTFORMAT, szMessage, BUFSIZE ); /* strcpy(szMessage, "This is frame #%d"); int iLen = wsprintf(m_szText, szMessage, (int)(m_nFrame + 1)); // ... and write it as well. hr = AVIStreamWrite(m_psText, m_nFrame * 40, 1, m_szText, iLen + 1, AVIIF_KEYFRAME, NULL, NULL); if (hr != AVIERR_OK) { GlobalFreePtr(alpbi); m_bOK = FALSE; return FALSE; } */ GlobalFreePtr(alpbi); m_nFrame++; return TRUE; } //******************************************************// // 后面的是新添加的函数,前面作了部分修改 // //******************************************************// BOOL CAVIFile::AddFrame(XString sBitmapFile) { if (!FindFile(sBitmapFile)) return FALSE; CBitmap bitmap; if (LoadBMPImage(sBitmapFile,bitmap)) { AddFrame(bitmap); } return TRUE; } BOOL CAVIFile::LoadBMPImage(const TCHAR *filename,CBitmap& bitmap) { CFile file; if (!file.Open(filename, CFile::modeRead)) return FALSE; BITMAPFILEHEADER bmfHeader; if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader)) return FALSE; if (bmfHeader.bfType != ((WORD) ('M' << 8) | 'B')) return FALSE; DWORD nPackedDIBLen = file.GetLength() - sizeof(BITMAPFILEHEADER); HGLOBAL hDIB = ::GlobalAlloc(GMEM_FIXED, nPackedDIBLen); if (hDIB == 0) return FALSE; if (file.Read((LPSTR)hDIB, nPackedDIBLen) != nPackedDIBLen){ ::GlobalFree(hDIB); return FALSE; } BITMAPINFOHEADER &bmiHeader = *(LPBITMAPINFOHEADER)hDIB ; BITMAPINFO &bmInfo = *(LPBITMAPINFO)hDIB ; int nColors = bmiHeader.biClrUsed ? bmiHeader.biClrUsed : 1 << bmiHeader.biBitCount; LPVOID lpDIBBits; if (bmInfo.bmiHeader.biBitCount > 8) { lpDIBBits = (LPVOID)((LPDWORD)(bmInfo.bmiColors + bmInfo.bmiHeader.biClrUsed) + ((bmInfo.bmiHeader.biCompression == BI_BITFIELDS) ? 3 : 0)); } else { lpDIBBits = (LPVOID)(bmInfo.bmiColors + nColors); } CClientDC dc(NULL); HBITMAP hBmp = CreateDIBitmap(dc.m_hDC, // handle to device context &bmiHeader, // pointer to bitmap size and format data CBM_INIT, // initialization flag lpDIBBits, // pointer to initialization data &bmInfo, // pointer to bitmap color-format data DIB_RGB_COLORS);// color-data usage bitmap.Attach(hBmp); ::GlobalFree(hDIB); return TRUE; } void CAVIFile::SetHasSaveOptionsDialog(BOOL bFlag) { m_bHasSaveOptionsDialog = bFlag; } BOOL CAVIFile::HasSaveOptionsDialog() { return m_bHasSaveOptionsDialog; } void CAVIFile::SetSaveOptionsParentWnd(HWND hWnd) { m_hSaveOptionsParentWnd = hWnd; } HWND CAVIFile::GetSaveOptionsParentWnd() { return m_hSaveOptionsParentWnd; } void CAVIFile::SetColorNum(UINT nColor) { m_nColorNum = nColor; } UINT CAVIFile::GetColorNum() { return m_nColorNum; }