在 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 不提供文件扩展名。 如果 StgMedium 的 lpszFileName 成员为 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;
}