用DirectShow旋转图片、播放Gif图片

 最近,在研读《COM技术内幕》和《DirectShow开发指南》从中学到不少的知识。如果有想从事多媒体开发的同志,这两本书有必要的好好研究一下。

     下面是我自己写的两个函数:一个是用显示旋转图片,一个是用于播放Gif图片文件。

 /* 解释: 旋转图片 参数: szFileName [in] : 图片的路径 fRAngle [in] : 旋转的角度 0 、90、180、270、360 hdc [in] : 绘图设备环境句柄 rcDraw [in] : 绘图的区域 */ void DrawImage(PTSTR szFileName,FLOAT fRAngle,HDC hdc ,const RECT& rcDraw) { HRESULT hr ; //返回结果 IImagingFactory * pImagingFactory =NULL; //Image工厂接口对象 IImage * pImage = NULL,* pNewImage = NULL; //Image接口对象;新的IImage图像 IBitmapImage * pbmpImg = NULL,* pNewbmpImg = NULL; //GIF/PNG/JPG图像;旋转后的图像 IBasicBitmapOps * pbmpOp = NULL; //旋转操作 ImageInfo imageInfo; //初始化COM环境 if (FAILED(hr = CoInitializeEx(NULL, COINIT_MULTITHREADED))) { RETAILMSG(TRUE,(TEXT("COINIT_MULTITHREADED ERROR/r/n"))); return; } //得到Image工厂接口对象 hr = CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**) &pImagingFactory); if (FAILED(hr)) { RETAILMSG(TRUE,(TEXT("IMAGE FACTORY CREATED ERROR/r/n"))); goto END; } //加载图象文件到IImage接口对象中 hr = pImagingFactory->CreateImageFromFile(szFileName,&pImage); if (FAILED(hr)) { RETAILMSG(TRUE,(TEXT("IMAGE LOAD ERROR/r/n"))); goto END; } //获得原图片的基本信息 pImage-> GetImageInfo(&imageInfo); //加载图像文件到IImage接口对象中 pImagingFactory->CreateBitmapFromImage(pImage,imageInfo.Width,imageInfo.Height,imageInfo.PixelFormat,InterpolationHintDefault,&pbmpImg); //查询某个组件是否支持某个特定的接口,若支持则QueryInterface则返回一个指向特定接口的指针;若不支持则返回一个错误代码 hr = pbmpImg->QueryInterface(IID_IBasicBitmapOps,(void **)&pbmpOp); //顺时针旋转 pbmpOp->Rotate(fRAngle,InterpolationHintDefault,&pNewbmpImg); //IBitmapImage对象->IImage对象 hr = pNewbmpImg->QueryInterface(IID_IImage,(void **)&pNewImage); //绘制图片 pNewImage->Draw(hdc, &rcDraw, NULL); END: //释放IImage接口对象 if(pNewImage) pNewImage->Release(); //释放IBitmapImage接口对象 if(pNewbmpImg) pNewbmpImg->Release(); //释放IBasicBitmapOps接口对象 if(pbmpOp) pbmpOp->Release(); //释放IBitmapImage接口对象 if(pbmpImg) pbmpImg->Release(); //释放IImage接口对象 if (pImage) pImage->Release(); //释放IImagingFactory接口对象 if (pImagingFactory) pImagingFactory->Release(); //释放程序占用的COM资源 CoUninitialize(); } /* 解释:从指定的文件中创建流对象 参数: szFileName [in] : 文件路径 返回: 返回一个流对象指针 */ IStream* CreateStreamByFileName(LPCTSTR strFileName) { //打开文件 HANDLE hFile = CreateFile(strFileName, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) { return 0; } //获取文件的大小 DWORD dwFileSize = GetFileSize(hFile, NULL); if (dwFileSize == (DWORD)-1) { CloseHandle(hFile); return 0; } //分配内存空间 HGLOBAL hGlobal = GlobalAlloc(GMEM_MOVEABLE, dwFileSize); if (hGlobal == NULL) { CloseHandle(hFile); return 0; } //锁定内存,并且获取指向内存的指针 LPVOID pvData = GlobalLock(hGlobal); if (pvData == NULL) { GlobalUnlock(hGlobal); CloseHandle(hFile); return 0; } DWORD dwBytesRead = 0; BOOL bRead = ReadFile(hFile, pvData, dwFileSize, &dwBytesRead, NULL); //解除内存 GlobalUnlock(hGlobal); CloseHandle(hFile); if (!bRead) { return 0; } IStream* pStream = 0; //从指定的内存(hGlobal)创建流对象(pStream) if (FAILED(CreateStreamOnHGlobal(hGlobal, TRUE, &pStream))) { return 0; } return pStream; } /* 解释: 播放Gif格式图片 参数: szFileName [in] : 图片的路径 hdc [in] : 绘图设备环境句柄 rcDraw [in] : 绘图的区域 */ void PlayGifImage(LPCTSTR strFileName,HDC hdc,const RECT &rcDraw) { IImagingFactory *pImgFactory = NULL; //Image工厂接口对象 IImage *pImage = NULL; //Image接口对象 ImageInfo *info = NULL; IStream* pStream = CreateStreamByFileName(strFileName); //创建流对象 IImageDecoder* pDecoder = NULL; // IImageDecoder接口对象 UINT count = 0; // 帧数 UINT size = 0; ImageInfo ii = {0}; PropertyItem *pi = NULL; GUID guid; UINT i = 0; IBitmapImage *bmpimg = NULL; IImageSink *sink = NULL; LARGE_INTEGER dlibMove = { 0, 0 }; //初始化COM环境 if (FAILED(CoInitializeEx(NULL, COINIT_MULTITHREADED))) { return; } if (SUCCEEDED(CoCreateInstance (CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void **)&pImgFactory))) { if (SUCCEEDED(pImgFactory->CreateImageDecoder(pStream, DecoderInitFlagNone, &pDecoder))) { pDecoder->TerminateDecoder(); pStream->Seek( dlibMove, STREAM_SEEK_SET, NULL ); pDecoder->InitDecoder(pStream, DecoderInitFlagBuiltIn1st); pDecoder->GetPropertyItemSize(PropertyTagFrameDelay, &size); pi = reinterpret_cast<PropertyItem *>(malloc(size)); pDecoder->GetPropertyItem(PropertyTagFrameDelay, size, pi); pDecoder->GetImageInfo(&ii); pDecoder->GetFrameDimensionsCount(&count); pDecoder->GetFrameDimensionsList(&guid, count); pDecoder->GetFrameCount(&guid, &count); while(TRUE) { if(i >= count) i = 0; pDecoder->SelectActiveFrame(&guid,i); pImgFactory->CreateNewBitmap(ii.Width, ii.Height, PixelFormatDontCare, &bmpimg); bmpimg->QueryInterface(IID_IImageSink, (void**)&sink); HRESULT hr = pDecoder->BeginDecode(sink, NULL); pDecoder->Decode(); bmpimg->QueryInterface(IID_IImage, (void**)&pImage); pImage->Draw(hdc, &rcDraw, NULL); DWORD dwSleep = (reinterpret_cast<DWORD *>(pi->value)[i]) * 10; Sleep(dwSleep); pDecoder->EndDecode(hr); ++i; } } } //释放程序占用的资源 if(pi) free(pi); if(pImgFactory) pImgFactory->Release(); if(pImage) pImage->Release(); if(pDecoder) pDecoder->Release(); if(bmpimg) bmpimg->Release(); if(sink) sink->Release(); if(pStream) pStream->Release(); CoUninitialize(); } 

 

 

 

你可能感兴趣的:(image,server,Stream,null,Integer,float)