Übertragen von Bilddaten in WIA 2.0
Hinweis
In diesem Tutorial wird veranschaulicht, wie Sie Imagedaten in Anwendungen übertragen, die unter Windows Vista oder höher ausgeführt werden. Informationen zum Übertragen von Imagedaten in Anwendungen, die unter Windows XP oder früher ausgeführt werden, finden Sie unter Übertragen von Bilddaten in WIA 1.0 .
Da die Bilddatenübertragung in Windows Image Acquisition (WIA) 2.0 streambasiert ist, müssen Sie keinen Zieltyp angeben (z. B. Arbeitsspeicher oder Datei). Die Anwendung gibt WIA 2.0 einfach den zu verwendenden Stream, und der Treiber liest oder schreibt in den Stream. Der Stream kann ein Dateidatenstrom, ein Speicherdatenstrom oder ein beliebiger anderer Streamtyp sein und ist für den Treiber transparent. Die Verwendung von Streams ermöglicht auch eine einfache Integration in den Bildverarbeitungsfilter.
Verwenden Sie die Methoden der IWiaTransfer-Schnittstelle , um Daten von einem WIA 2.0-Gerät an eine Anwendung zu übertragen. Diese Schnittstelle ist über die IWiaItem2-Schnittstelle verfügbar. Die IWiaTransfer-Schnittstelle verfügt über Methoden zum Anfordern des Hochladens oder Herunterladens von Daten auf und von einem Gerät. Diese Methoden führen einen Rückruf durch, den die Anwendung bereitstellt, und verwenden einen von der Anwendung bereitgestellten IStream für das tatsächliche Ziel der Datenübertragung.
Anwendungen müssen ein Bildelement abfragen, um einen Zeiger auf die IWiaTransfer-Schnittstelle abzurufen, wie im folgenden Codebeispiel gezeigt:
// Get the IWiaTransfer interface
//
IWiaTransfer *pWiaTransfer = NULL;
hr = pIWiaItem2->QueryInterface(IID_IWiaTransfer,(void**)&pWiaTransfer);
Im vorherigen Code wird davon ausgegangen, dass pWiaItem2 ein gültiger Zeiger auf die IWiaItem2-Schnittstelle ist. Der Aufruf von IUnknown::QueryInterface füllt pWiaTransfer mit einem Zeiger auf die IWiaTransfer-Schnittstelle des Elements, auf das von pWiaItem2 verwiesen wird.
Die Anwendung instanziiert dann das Rückrufobjekt, wie hier gezeigt.
// Instantiate the object which receives the callbacks
//
CWiaTransferCallback *pWiaClassCallback = new CWiaTransferCallback;
Die Anwendung legt als Nächstes die Eigenschaften mithilfe der IWiaPropertyStorage-Schnittstelle des IWiaItem2-Elements fest und führt die Übertragung aus.
Downloadvorgang läuft:
// Download
hr = pWiaTransfer->Download(0,pWiaClassCallback);
Hochladen:
//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);
}
}
}
Hier sehen Sie das vollständige Beispiel für die Datenübertragung:
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;
};