HRESULT EnumerateItems( IWiaItem *pWiaItem ) { // // Validate arguments // if (NULL == pWiaItem) { return E_INVALIDARG; } // // Get the item type for this item // LONG lItemType = 0; HRESULT hr = pWiaItem->GetItemType( &lItemType ); // // Do something with this item. Print the item name. // PrintItemName( pWiaItem ); // // If this is an image, transfer it // if (lItemType & WiaItemTypeImage) { hr = TransferWiaItem( pWiaItem ); } // // If it is a folder, or it has attachments, enumerate its children // if (lItemType & WiaItemTypeFolder || lItemType & WiaItemTypeHasAttachments) { // // Get the child item enumerator for this item // IEnumWiaItem *pEnumWiaItem = NULL; hr = pWiaItem->EnumChildItems( &pEnumWiaItem ); if (SUCCEEDED(hr)) { // // We will loop until we get an error or pEnumWiaItem->Next returns // S_FALSE to signal the end of the list. // while (S_OK == hr) { // // Get the next child item // IWiaItem *pChildWiaItem = NULL; hr = pEnumWiaItem->Next( 1, &pChildWiaItem, NULL ); // // pEnumWiaItem->Next will return S_FALSE when the list is // exhausted, so check for S_OK before using the returned // value. // if (S_OK == hr) { // // Recurse into this item // hr = EnumerateItems( pChildWiaItem ); // // Release this item // pChildWiaItem->Release(); pChildWiaItem = NULL; } else if (FAILED(hr)) { // // Report that an error occurred during enumeration // ReportError( TEXT("Error calling pEnumWiaItem->Next"), hr ); } } // // If the result of the enumeration is S_FALSE, since this // is normal, we will change it to S_OK // if (S_FALSE == hr) { hr = S_OK; } // // Release the enumerator // pEnumWiaItem->Release(); pEnumWiaItem = NULL; } } return hr; }
HRESULT CreateWiaDeviceAndDoSomeStuff( IWiaDevMgr *pWiaDevMgr, IWiaPropertyStorage *pWiaPropertyStorage ) { // // Validate arguments // if (NULL == pWiaPropertyStorage) { return E_INVALIDARG; } // // Declare PROPSPECs and PROPVARIANTs, and initialize them to zero. // PROPSPEC PropSpec[1] = {0}; PROPVARIANT PropVar[1] = {0}; // // How many properties are we querying for? // const ULONG c_nPropertyCount = sizeof(PropSpec)/sizeof(PropSpec[0]); // // Define which properties we want to read. We want the // device ID, so we can create the device. // PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = WIA_DIP_DEV_ID; // // Ask for the property values // HRESULT hr = pWiaPropertyStorage->ReadMultiple( c_nPropertyCount, PropSpec, PropVar ); if (SUCCEEDED(hr)) { // // Check the return type for the device ID to make // sure this property was actually read. // if (VT_BSTR == PropVar[0].vt) { // // Create the WIA device, which results in obtaining // the root IWiaItem // IWiaItem *pWiaRootItem = NULL; hr = CreateWiaDevice( pWiaDevMgr, PropVar[0].bstrVal, &pWiaRootItem ); if (SUCCEEDED(hr)) { // // Recursively enumerate the items // (This function will also do some stuff with each item) // hr = EnumerateItems( pWiaRootItem ); // // Free the root item // pWiaRootItem->Release(); pWiaRootItem = NULL; } else { ReportError( TEXT("Error calling CreateWiaDevice"), hr ); } } // // Free the returned PROPVARIANTs // FreePropVariantArray( c_nPropertyCount, PropVar ); } else { ReportError( TEXT("Error calling IWiaPropertyStorage::ReadMultiple"), hr ); } // // Return the result of all of this // return hr; }
HRESULT WIACamera::DigitalCameraCapture(IWiaItem* pIWiaRoot, IplImage** ppIplImage) { HRESULT hr = S_OK; IWiaItem* pIWiaItem = NULL; hr = pIWiaRoot->DeviceCommand( 0, &WIA_CMD_TAKE_PICTURE, &pIWiaItem ); if (pIWiaItem==NULL) { cvReleaseImage(ppIplImage); (*ppIplImage) = NULL; return hr; } IStream **ppStream = NULL; LONG lCount = 0; // Create the data callback interface CDataCallback *pDataCallback = new CDataCallback( &lCount,&ppStream ); if (pDataCallback == NULL) { return E_OUTOFMEMORY; } { // Get the interface pointers IWiaPropertyStorage *pWiaPropertyStorage; hr = pIWiaItem->QueryInterface(IID_IWiaPropertyStorage,(void**)&pWiaPropertyStorage); if (hr != S_OK) { return E_NOINTERFACE; } IWiaDataTransfer *pIWiaDataTransfer; hr = pIWiaItem->QueryInterface(IID_IWiaDataTransfer, (void**)&pIWiaDataTransfer); if (hr != S_OK) { return E_NOINTERFACE; } // Set the transfer type PROPSPEC specTymed; specTymed.ulKind = PRSPEC_PROPID; specTymed.propid = WIA_IPA_TYMED; PROPVARIANT varTymed; varTymed.vt = VT_I4; varTymed.lVal = TYMED_CALLBACK; hr = pWiaPropertyStorage->WriteMultiple(1, &specTymed, &varTymed, WIA_IPA_FIRST ); PropVariantClear(&varTymed); if (FAILED(hr)) { return hr; } // If there is no transfer format specified, use the device default GUID guidFormat = GUID_NULL; GUID *pguidFormat = &guidFormat; PROPSPEC specPreferredFormat; specPreferredFormat.ulKind = PRSPEC_PROPID; specPreferredFormat.propid = WIA_IPA_PREFERRED_FORMAT; hr = ReadPropertyGuid( pWiaPropertyStorage, &specPreferredFormat, pguidFormat ); if (FAILED(hr)) { return hr; } // Set the transfer format PROPSPEC specFormat; PROPVARIANT varFormat; specFormat.ulKind = PRSPEC_PROPID; specFormat.propid = WIA_IPA_FORMAT; varFormat.vt = VT_CLSID; varFormat.puuid = (CLSID *) CoTaskMemAlloc(sizeof(CLSID)); if (varFormat.puuid == NULL) { return E_OUTOFMEMORY; } *varFormat.puuid = *pguidFormat; hr = pWiaPropertyStorage->WriteMultiple( 1, &specFormat, &varFormat, WIA_IPA_FIRST ); PropVariantClear(&varFormat); if (FAILED(hr)) { return hr; } // Read the transfer buffer size from the device, default to 64K PROPSPEC specBufferSize; specBufferSize.ulKind = PRSPEC_PROPID; specBufferSize.propid = WIA_IPA_BUFFER_SIZE; LONG nBufferSize; hr = ReadPropertyLong( pWiaPropertyStorage, &specBufferSize, &nBufferSize ); if (FAILED(hr)) { nBufferSize = 64 * 1024; } // Choose double buffered transfer for better performance WIA_DATA_TRANSFER_INFO WiaDataTransferInfo = { 0 }; WiaDataTransferInfo.ulSize = sizeof(WIA_DATA_TRANSFER_INFO); WiaDataTransferInfo.ulBufferSize = 2 * nBufferSize; WiaDataTransferInfo.bDoubleBuffer = TRUE; // Start the transfer hr = pIWiaDataTransfer->idtGetBandedData( &WiaDataTransferInfo, pDataCallback ); if (pWiaPropertyStorage) { pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } if (pIWiaDataTransfer) { pIWiaDataTransfer->Release(); pIWiaDataTransfer = NULL; } } if (pIWiaItem) { // Delete file from DigitalCamera storage pIWiaItem->DeleteItem(0); pIWiaItem->Release(); pIWiaItem = NULL; } if (lCount!=1) throw "Error.\n"; if ( SUCCEEDED(hr) ) { Gdiplus::Bitmap myBmp(ppStream[0]); int Width = myBmp.GetWidth(); int Height = myBmp.GetHeight(); Gdiplus::Rect rect(0, 0, Width, Height); Gdiplus::BitmapData myBitmapData; Gdiplus::Status res = myBmp.LockBits( &rect, Gdiplus::ImageLockModeRead, PixelFormat24bppRGB, &myBitmapData ); if ( (*ppIplImage)==NULL ) { (*ppIplImage) = cvCreateImage(cvSize(Width,Height),IPL_DEPTH_8U,3); } else { CvSize oldSize = cvGetSize((*ppIplImage)); if ( oldSize.width!=Width || oldSize.height!=Height ) { throw "Warning.\n"; cvReleaseImage(&(*ppIplImage)); (*ppIplImage) = cvCreateImage(cvSize(Width,Height),IPL_DEPTH_8U,3); } } unsigned char *pIplData = (unsigned char*)(*ppIplImage)->imageData; for ( int h=0; h < Height; h++) { unsigned char *pIplLine = &pIplData[(*ppIplImage)->widthStep*h]; unsigned char *pBitmapLine = &((unsigned char*)myBitmapData.Scan0)[myBitmapData.Stride*h]; memcpy( pIplLine, pBitmapLine, sizeof(unsigned char)*Width*3 ); /* for ( int w=0; w < Width; w++) { pIplLine[w*3+0] = pBitmapLine[w*3+2]; pIplLine[w*3+1] = pBitmapLine[w*3+1]; pIplLine[w*3+2] = pBitmapLine[w*3+0]; } */ } } else { delete (*ppIplImage); (*ppIplImage) = NULL; } ppStream[0]->Release(); return hr; }