网页功能: 加入收藏 设为首页 网站搜索  
读取万能图片以及DShow的另类用法
发表日期:2007-01-18作者:[转贴] 出处:  


  我曾经有过一个想法,就是做一个万能的图片处理装置,今天我无意中将JPG的图片拖到了Media Player的里面,突然在Media Player的窗口里出现了JPG图片,于是我想到了用DShow显示图片的想法。可是普通的用HWND挂钩的方法根本就不行,怎么办呢?于是我察看MSDN的DShow函数库,发现了一个与DirectDraw习习相关的东西----------IDirectDrawMediaStream。

大家用百度或者在Gameres的网站里面搜索一下IDirectDrawMediaStream,就有一篇文章,这里给出地址:
http://www.gameres.com/articles/Program/Visual/Other/VCuseDS.htm

  大家可以看一下,这篇文章就是本文章的前篇,对于新手们还有一个问题,《在VC中调用DirectShow全屏播放视频》的方法中利用了DirectDraw 和 DirectDrawSurface ,而不是最流行的DirectDraw7 和 DirectDrawSurface7,MSDN说了这一句:

Use QueryInterface to obtain the IDirectDrawSurface interface from an IDirectDrawSurface7 interface.

  我想到了QueryInterface。

  QueryInterface通俗的讲就是COM模型的“强制转换”,呵呵,或许你已经知道我要怎么做了,没错,用一个临时的DirectDraw 和 DirectDrawSurface 。

代码如下:
//------------------------------------------------------------------------------------------------

#include <stdio.h>
#include <ddraw.h> // DirectDraw interfaces
#pragma comment(lib,"ddraw.lib")
#pragma comment(lib,"dxguid.lib")
#include "mmstream.h" // multimedia stream interfaces
#include "amstream.h" // DirectShow multimedia stream interfaces
#include "ddstream.h" // DirectDraw multimedia stream interfaces
#pragma comment(lib,"strmiids.lib")

HRESULT RenderStreamToSurface(IDirectDrawSurface *pSurface, IMultiMediaStream *pMMStream)
{
    IMediaStream *pPrimaryVidStream;
    IDirectDrawMediaStream *pDDStream;
    IDirectDrawStreamSample *pSample;
    RECT rect;
    DDSURFACEDESC ddsd;

    HRESULT hr;
    hr = pMMStream->GetMediaStream(MSPID_PrimaryVideo, &pPrimaryVidStream);
    if (FAILED(hr))
    {
        return hr;
    }
    pPrimaryVidStream->QueryInterface(IID_IDirectDrawMediaStream, (void **)&pDDStream);

    ddsd.dwSize = sizeof(ddsd);
    hr = pDDStream->GetFormat(&ddsd, NULL, NULL, NULL);
    if (SUCCEEDED(hr))
    {
        rect.top = rect.left = 0;
        rect.bottom = ddsd.dwHeight;
        rect.right = ddsd.dwWidth;
        hr = pDDStream->CreateSample(pSurface, &rect, 0, &pSample);
        if (SUCCEEDED(hr))
        {
            pMMStream->SetState(STREAMSTATE_RUN);
            while (pSample->Update(0, NULL, NULL, NULL) == S_OK)
            {
                // Empty loop.
            }
            pMMStream->SetState(STREAMSTATE_STOP);
            pSample->Release();
        }
    }
    pDDStream->Release();
    pPrimaryVidStream->Release();
    return hr;
}

HRESULT RenderFileToMMStream(
const char * szFileName,
IMultiMediaStream **ppMMStream,
IDirectDraw *pDD)
{
    if (strlen(szFileName) > MAX_PATH)
    {
        return E_INVALIDARG;
    }

    IAMMultiMediaStream *pAMStream;
    HRESULT hr = CoCreateInstance(CLSID_AMMultiMediaStream, NULL, CLSCTX_INPROC_SERVER, IID_IAMMultiMediaStream, (void **)&pAMStream);
    if (FAILED(hr))
    {
        return hr;
    }

    WCHAR wPath[MAX_PATH + 1];
    MultiByteToWideChar(CP_ACP, 0, szFileName, -1, wPath, MAX_PATH + 1);

    pAMStream->Initialize(STREAMTYPE_READ, AMMSF_NOGRAPHTHREAD, NULL);
    pAMStream->AddMediaStream(pDD, &MSPID_PrimaryVideo, 0, NULL);
    pAMStream->AddMediaStream(NULL, &MSPID_PrimaryAudio, AMMSF_ADDDEFAULTRENDERER, NULL);
    hr = pAMStream->OpenFile(wPath, 0);
    if (SUCCEEDED(hr))
    {
        hr = pAMStream->QueryInterface(IID_IMultiMediaStream, (void**)ppMMStream);
    }
    pAMStream->Release();
    return hr;
}

int __cdecl main(int argc, char *argv[])
{
    if (argc < 2)
    {
        printf("Usage : showstrm movie.ext\n");
        exit(0);
    }

    DDSURFACEDESC2 ddsd;
    LPDIRECTDRAW7 pDD;
    LPDIRECTDRAWSURFACE7 pPrimarySurface;
    IMultiMediaStream *pMMStream;

    CoInitialize(NULL);
    DirectDrawCreateEx (NULL, (void **)&pDD, IID_IDirectDraw7, NULL);
    pDD->SetCooperativeLevel(GetDesktopWindow(), DDSCL_NORMAL);
    ZeroMemory(&ddsd, sizeof(ddsd));//设置页面内存大小
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
    pDD->CreateSurface(&ddsd, &pPrimarySurface, NULL);
    LPDIRECTDRAW pDD1;
    LPDIRECTDRAWSURFACE pPrimarySurface1;
    pPrimarySurface->QueryInterface(IID_IDirectDrawSurface,(LPVOID*)&pPrimarySurface1);
    pPrimarySurface->Release();
    pDD->QueryInterface(IID_IDirectDraw,(LPVOID*)&pDD1);
    pDD->Release();

    HRESULT hr = RenderFileToMMStream(argv[1], &pMMStream,pDD1);

    if (SUCCEEDED(hr))
    {
        RenderStreamToSurface(pPrimarySurface1, pMMStream);
        pMMStream->Release();
    }
    pPrimarySurface1->Release();
    pDD1->Release();
    CoUninitialize();
    return 0;
}

我来说两句】 【加入收藏】 【返加顶部】 【打印本页】 【关闭窗口
中搜索 读取万能图片以及DShow的另类用法
本类热点文章
  DirectShow应用——支持Windows Media格..
  DirectShow PIN 連接教學
  游戏UI设计1
  PSD格式文件的读取
  将RGB值转换为灰度值的简单算法
  貼圖 filtering 與 MIP map 簡介
  读取万能图片以及DShow的另类用法
  TGA图像文件格式资料
  DirectShow初探
  PNG格式
  DirectShow应用——支持DVD播放
  DirectShow的中文资料之建立一个捕捉程序
最新分类信息我要发布 
最新招聘信息

关于我们 / 合作推广 / 给我留言 / 版权举报 / 意见建议 / 广告投放  
Copyright ©2003-2024 Lihuasoft.net webmaster(at)lihuasoft.net
网站编程QQ群   京ICP备05001064号 页面生成时间:0.00422