在 WIA 1.0 中传输图像数据

注意

本教程介绍如何在将运行 Windows XP 或更早版本的应用程序中传输图像数据。 有关在将在 Windows Vista 或更高版本上运行的应用程序中传输图像数据的信息,请参阅 在 WIA 2.0 中传输图像数据。

 

使用 IWiaDataTransfer 接口的方法将数据从 Windows 映像采集 (WIA) 1.0 设备传输到应用程序。 此接口支持使用共享内存窗口将数据从设备对象传输到应用程序,并在封送期间消除不必要的数据副本。

应用程序必须查询图像项才能获取指向其 IWiaDataTransfer 接口的指针,如以下代码示例所示:

    // Get the IWiaDataTransfer interface
    //
    IWiaDataTransfer *pWiaDataTransfer = NULL;
    hr = pWiaItem->QueryInterface( IID_IWiaDataTransfer, (void**)&pWiaDataTransfer );

在前面的代码中,假定 pWiaItem 是指向 IWiaItem 接口的有效指针。 对 IUnknown::QueryInterface 的调用使用指向 pWiaItem 引用的项的 IWiaDataTransfer 接口的指针填充 pWiaDataTransfer

然后,应用程序设置 STGMEDIUM 结构成员。 有关信息,请参阅 STGMEDIUM 和 TYMED

    // Set storage medium
    //
    STGMEDIUM StgMedium = {0};
    StgMedium.tymed = TYMED_FILE;

如果提供文件名,则它应包含正确的文件扩展名;WIA 1.0 不提供文件扩展名。 如果 StgMediumlpszFileName 成员为 NULL,WIA 1.0 会为传输的数据生成随机文件名和路径。 在调用 ReleaseStgMedium 之前移动或复制此文件,因为此函数将删除该文件。

然后,应用程序调用 IWiaDataTransfer::idtGetData 方法来运行数据传输:

    // Perform the transfer
    //
    hr = pWiaDataTransfer->idtGetData( &stgMedium, pWiaDataCallback );

在调用 IWiaDataTransfer::idtGetData 时,第二个参数指定指向 IWiaDataCallback 接口的指针。 应用程序必须实现此接口才能在数据传输期间接收回调。 有关实现此接口的信息,请参阅 IWiaDataCallback::BandedDataCallback

然后,应用程序释放指向 IWiaDataTransfer 接口的指针,并释放 STGMEDIUM 结构中分配的任何数据。

应用程序还可以使用内存中数据传输而不是文件传输来传输映像。 在这种情况下,应用程序使用 idtGetBandedData 方法代替 idtGetData 方法。

下面是完整的数据传输示例:

HRESULT TransferWiaItem( IWiaItem *pWiaItem )
{
    //
    // Validate arguments
    //
    if (NULL == pWiaItem)
    {
        return E_INVALIDARG;
    }

    //
    // Get the IWiaPropertyStorage interface so you can set required properties.
    //
    IWiaPropertyStorage *pWiaPropertyStorage = NULL;
    HRESULT hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage );
    if (SUCCEEDED(hr))
    {
        //
        // Prepare PROPSPECs and PROPVARIANTs for setting the
        // media type and format
        //
        PROPSPEC PropSpec[2] = {0};
        PROPVARIANT PropVariant[2] = {0};
        const ULONG c_nPropCount = sizeof(PropVariant)/sizeof(PropVariant[0]);

        //
        // Use BMP as the output format
        //
        GUID guidOutputFormat = WiaImgFmt_BMP;

        //
        // Initialize the PROPSPECs
        //
        PropSpec[0].ulKind = PRSPEC_PROPID;
        PropSpec[0].propid = WIA_IPA_FORMAT;
        PropSpec[1].ulKind = PRSPEC_PROPID;
        PropSpec[1].propid = WIA_IPA_TYMED;

        //
        // Initialize the PROPVARIANTs
        //
        PropVariant[0].vt = VT_CLSID;
        PropVariant[0].puuid = &guidOutputFormat;
        PropVariant[1].vt = VT_I4;
        PropVariant[1].lVal = TYMED_FILE;

        //
        // Set the properties
        //
        hr = pWiaPropertyStorage->WriteMultiple( c_nPropCount, PropSpec, PropVariant, WIA_IPA_FIRST );
        if (SUCCEEDED(hr))
        {
            //
            // Get the IWiaDataTransfer interface
            //
            IWiaDataTransfer *pWiaDataTransfer = NULL;
            hr = pWiaItem->QueryInterface( IID_IWiaDataTransfer, (void**)&pWiaDataTransfer );
            if (SUCCEEDED(hr))
            {
                //
                // Create our callback class
                //
                CWiaDataCallback *pCallback = new CWiaDataCallback;
                if (pCallback)
                {
                    //
                    // Get the IWiaDataCallback interface from our callback class.
                    //
                    IWiaDataCallback *pWiaDataCallback = NULL;
                    hr = pCallback->QueryInterface( IID_IWiaDataCallback, (void**)&pWiaDataCallback );
                    if (SUCCEEDED(hr))
                    {
                        //
                        // Perform the transfer using default settings
                        //
                        STGMEDIUM stgMedium = {0};
                        StgMedium.tymed = TYMED_FILE;
                        hr = pWiaDataTransfer->idtGetData( &stgMedium, pWiaDataCallback );
                        if (S_OK == hr)
                        {
                            //
                            // Print the filename (note that this filename is always
                            // a WCHAR string, not TCHAR).
                            //
                            _tprintf( TEXT("Transferred filename: %ws\n"), stgMedium.lpszFileName );

                            //
                            // Release any memory associated with the stgmedium
                            // This will delete the file stgMedium.lpszFileName.
                            //
                            ReleaseStgMedium( &stgMedium );
                        }

                        //
                        // Release the callback interface
                        //
                        pWiaDataCallback->Release();
                        pWiaDataCallback = NULL;
                    }

                    //
                    // Release our callback.  It should now delete itself.
                    //
                    pCallback->Release();
                    pCallback = NULL;
                }

                //
                // Release the IWiaDataTransfer
                //
                pWiaDataTransfer->Release();
                pWiaDataTransfer = NULL;
            }
        }

        //
        // Release the IWiaPropertyStorage
        //
        pWiaPropertyStorage->Release();
        pWiaPropertyStorage = NULL;
    }

    return hr;
}