Transferencia de datos de imagen en WIA 2.0
Nota
En este tutorial se muestra cómo transferir datos de imagen en aplicaciones que se ejecutan en Windows Vista o versiones posteriores. Consulta Transferir datos de imagen en WIA 1.0 para obtener información sobre cómo transferir datos de imagen en aplicaciones que se ejecutan en Windows XP o versiones anteriores.
Dado que la transferencia de datos de imagen se basa en secuencias en la adquisición de imágenes de Windows (WIA) 2.0, no es necesario especificar un tipo de destino (por ejemplo, memoria o archivo). La aplicación simplemente proporciona a WIA 2.0 la secuencia que se va a usar y el controlador lee o escribe en la secuencia. La secuencia puede ser una secuencia de archivos, una secuencia de memoria o cualquier otro tipo de secuencia, y es transparente para el controlador. El uso de secuencias también proporciona una integración sencilla con el filtro procesamiento de imágenes.
Usa los métodos de la interfaz IWiaTransfer para transferir datos de un dispositivo WIA 2.0 a una aplicación. Esta interfaz está disponible a través de la interfaz IWiaItem2 . La interfaz IWiaTransfer tiene métodos para solicitar la carga o descarga de datos hacia y desde un dispositivo. Estos métodos toman una devolución de llamada que proporciona la aplicación y usan un IStream proporcionado por la aplicación para el destino real de la transferencia de datos.
Las aplicaciones deben consultar un elemento de imagen para obtener un puntero a su interfaz IWiaTransfer , como se muestra en el ejemplo de código siguiente:
// Get the IWiaTransfer interface
//
IWiaTransfer *pWiaTransfer = NULL;
hr = pIWiaItem2->QueryInterface(IID_IWiaTransfer,(void**)&pWiaTransfer);
En el código anterior, se supone que pWiaItem2 es un puntero válido a la interfaz IWiaItem2 . La llamada a IUnknown::QueryInterface rellena pWiaTransfer con un puntero a la interfaz IWiaTransfer del elemento al que hace referencia pWiaItem2.
A continuación, la aplicación crea una instancia del objeto de devolución de llamada, como se muestra aquí.
// Instantiate the object which receives the callbacks
//
CWiaTransferCallback *pWiaClassCallback = new CWiaTransferCallback;
A continuación, la aplicación establece las propiedades mediante la interfaz IWiaPropertyStorage del elemento IWiaItem2 y realiza la transferencia.
Descarga:
// Download
hr = pWiaTransfer->Download(0,pWiaClassCallback);
Cargar:
//Create child item which eventually will be the uploaded image
IWiaItem2* pWiaItemChild = NULL;
HRESULT hr = pIWiaItem2->CreateChildItem(WiaItemTypeImage|WiaItemTypeFile,0,bzUploadFileName,&pWiaItemChild);
if(SUCCEEDED(hr))
{
//Set the format for the child item as BMP
IWiaPropertyStorage* pWiaChildPropertyStorage = NULL;
hr = pWiaItemChild->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaChildPropertyStorage );
if(SUCCEEDED(hr))
{
WritePropertyGuid(pWiaChildPropertyStorage,WIA_IPA_FORMAT,WiaImgFmt_BMP );
//release pWiaChildPropertyStorage
pWiaChildPropertyStorage->Release();
pWiaChildPropertyStorage = NULL;
}
//Get the IWiaTransfer interface of the child
IWiaTransfer* pWiaTransferChild = NULL;
hr = pWiaItemChild->QueryInterface( IID_IWiaTransfer, (void**)&pWiaTransferChild );
if(SUCCEEDED(hr)){
IStream* pUploadStream = NULL;
//Create stream on test.BMP file
hr = SHCreateStreamOnFile(L"test.BMP",STGM_READ, &pUploadStream);
if(SUCCEEDED(hr)){
pWiaTransferChild->Upload(0,pUploadStream,pWiaClassCallback);
}
}
}
Este es el ejemplo completo de transferencia de datos:
HRESULT TransferWiaItem( IWiaItem2 *pIWiaItem2)
{
// Validate arguments
if (NULL == pIWiaItem2)
{
_tprintf(TEXT("\nInvalid parameters passed"));
return E_INVALIDARG;
}
// Get the IWiaTransfer interface
IWiaTransfer *pWiaTransfer = NULL;
HRESULT hr = pIWiaItem2->QueryInterface( IID_IWiaTransfer, (void**)&pWiaTransfer );
if (SUCCEEDED(hr))
{
// Create our callback class
CWiaTransferCallback *pWiaClassCallback = new CWiaTransferCallback;
if (pWiaClassCallback)
{
LONG lItemType = 0;
hr = pIWiaItem2->GetItemType( &lItemType );
//download all items which have WiaItemTypeTransfer flag set
if(lItemType & WiaItemTypeTransfer)
{
// If it is a folder, do folder download . Hence with one API call, all the leaf nodes of this folder
// will be transferred
if ((lItemType & WiaItemTypeFolder))
{
_tprintf ( L"\nI am a folder item");
hr = pWiaTransfer->Download(WIA_TRANSFER_ACQUIRE_CHILDREN, pWiaClassCallback);
if(S_OK == hr)
{
_tprintf(TEXT("\npWiaTransfer->Download() on folder item SUCCEEDED"));
}
else if(S_FALSE == hr)
{
ReportError(TEXT("\npWiaTransfer->Download() on folder item returned S_FALSE. Folder may not be having child items"),hr);
}
else if(FAILED(hr))
{
ReportError(TEXT("\npWiaTransfer->Download() on folder item failed"),hr);
}
}
// If this is an file type, do file download
else if (lItemType & WiaItemTypeFile )
{
hr = pWiaTransfer->Download(0,pWiaClassCallback);
if(S_OK == hr)
{
_tprintf(TEXT("\npWiaTransfer->Download() on file item SUCCEEDED"));
}
else if(S_FALSE == hr)
{
ReportError(TEXT("\npWiaTransfer->Download() on file item returned S_FALSE. File may be empty"),hr);
}
else if(FAILED(hr))
{
ReportError(TEXT("\npWiaTransfer->Download() on file item failed"),hr);
}
}
}
// Release our callback. It should now delete itself.
pWiaClassCallback->Release();
pWiaClassCallback = NULL;
}
else
{
ReportError( TEXT("\nUnable to create CWiaTransferCallback class instance") );
}
// Release the IWiaTransfer
pWiaTransfer->Release();
pWiaTransfer = NULL;
}
else
{
ReportError( TEXT("\npIWiaItem2->QueryInterface failed on IID_IWiaTransfer"), hr );
}
return hr;
}
// Callback Class should be something like this:
class CWiaTransferCallback : public IWiaTransferCallback
{
public: // Constructors, destructor
CWiaTransferCallback () : m_cRef(1) {};
~ CWiaTransferCallback () {};
public: // IWiaTransferCallback
HRESULT __stdcall TransferCallback(
LONG lFlags,
WiaTransferParams *pWiaTransferParams)
{
HRESULT hr = S_OK;
switch (pWiaTransferParams->lMessage)
{
case WIA_TRANSFER_MSG_STATUS:
...
break;
case WIA_TRANSFER_MSG_END_OF_STREAM:
...
break;
case WIA_TRANSFER_MSG_END_OF_TRANSFER:
...
break;
default:
break;
}
return hr;
}
HRESULT __stdcall GetNextStream(
LONG lFlags,
BSTR bstrItemName,
BSTR bstrFullItemName,
IStream **ppDestination)
{
HRESULT hr = S_OK;
// Return a new stream for this item's data.
//
hr = CreateDestinationStream(bstrItemName, ppDestination);
return hr;
}
public: // IUnknown
.
.
. // Etc.
private:
/// For ref counting implementation
LONG m_cRef;
};