HRESULT WIACamera::GetDeviceProperty(const unsigned int CamID, const PropertyType Type, int *piValue) { HRESULT hr = S_OK; if ( CamID >= m_iCount ) return S_FALSE; IWiaPropertyStorage *pWiaPropertyStorage; hr = m_vRootItem[CamID]->QueryInterface(IID_IWiaPropertyStorage,(void**)&pWiaPropertyStorage); if (hr != S_OK) { return E_NOINTERFACE; } PROPSPEC PropSpec; PROPVARIANT PropVar; PropSpec.ulKind = PRSPEC_PROPID; if ( Type==CAMERA_SHUTTERSPEED ) { PropSpec.propid = WIA_DPC_EXPOSURE_TIME; hr = pWiaPropertyStorage->ReadMultiple( 1, &PropSpec, &PropVar ); } else if ( Type==CAMERA_GAIN ) { PropSpec.propid = WIA_DPC_EXPOSURE_INDEX; hr = pWiaPropertyStorage->ReadMultiple( 1, &PropSpec, &PropVar ); } else if ( Type==CAMERA_APERTURE ) { PropSpec.propid = WIA_DPC_FNUMBER; hr = pWiaPropertyStorage->ReadMultiple( 1, &PropSpec, &PropVar ); } else { hr = E_NOTIMPL; } if (pWiaPropertyStorage) { pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } if (hr == S_OK) { *piValue = (int)PropVar.lVal; } return hr; }
//This function enumerates WIA devices and then creates an instance of each device. //After that it calls EnumerateAndDownloadItems() on the root item got from creation of device. HRESULT EnumerateWiaDevices( IWiaDevMgr2 *pWiaDevMgr2 ) { // Validate arguments if (NULL == pWiaDevMgr2) { HRESULT hr = E_INVALIDARG; ReportError(TEXT("Invalid argument passed to EnumerateWiaDevices()"),hr); return hr; } // Get a device enumerator interface IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL; HRESULT hr = pWiaDevMgr2->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo ); if (SUCCEEDED(hr)) { // Reset the device enumerator to the beginning of the list hr = pWiaEnumDevInfo->Reset(); if (SUCCEEDED(hr)) { // We will loop until we get an error or pWiaEnumDevInfo->Next returns // S_FALSE to signal the end of the list. while (S_OK == hr) { // Get the next device's property storage interface pointer IWiaPropertyStorage *pWiaPropertyStorage = NULL; hr = pWiaEnumDevInfo->Next( 1, &pWiaPropertyStorage, NULL ); // pWiaEnumDevInfo->Next will return S_FALSE when the list is // exhausted, so check for S_OK before using the returned // value. if (hr == S_OK) { // Read some device properties - Device ID,name and descripion and return Device ID needed for creating Device BSTR bstrDeviceID = NULL; HRESULT hr1 = ReadWiaPropsAndGetDeviceID( pWiaPropertyStorage ,&bstrDeviceID); if(SUCCEEDED(hr1)) { // Call a function to create the device using device ID IWiaItem2 *pWiaRootItem2 = NULL; hr1 = pWiaDevMgr2->CreateDevice( 0, bstrDeviceID, &pWiaRootItem2 ); if(SUCCEEDED(hr1)) { // Enumerate items and for each item do transfer hr1 = EnumerateAndDownloadItems( pWiaRootItem2 ); if(FAILED(hr1)) { ReportError(TEXT("EnumerateAndDownloadItems() failed in EnumerateWiaDevices()"),hr1); } //Release pWiaRootItem2 pWiaRootItem2->Release(); pWiaRootItem2 = NULL; } else { ReportError(TEXT("Error calling IWiaDevMgr2::CreateDevice()"),hr1); } } else { ReportError(TEXT("ReadWiaPropsAndGetDeviceID() failed in EnumerateWiaDevices()"),hr1); } // Release the device's IWiaPropertyStorage* pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } else if (FAILED(hr)) { // Report that an error occurred during enumeration ReportError( TEXT("Error calling IEnumWIA_DEV_INFO::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; } } else { // Report that an error occurred calling Reset() ReportError( TEXT("Error calling IEnumWIA_DEV_INFO::Reset()"), hr ); } // Release the enumerator pWiaEnumDevInfo->Release(); pWiaEnumDevInfo = NULL; } else { // Report that an error occurred trying to create the enumerator ReportError( TEXT("Error calling IWiaDevMgr2::EnumDeviceInfo"), hr ); } // Return the result of the enumeration return hr; }
// This function downloads item after setting the format for the item and initializing callback (depending on category,itemtype) // with the directory to download images to as well as the filename for the downloaded image. HRESULT DownloadItem(IWiaItem2* pWiaItem2) { if( (!pWiaItem2) ) { HRESULT hr = E_INVALIDARG; ReportError(TEXT("Invalid argument passed to DownloadItem()"),hr); return hr; } // Get the IWiaTransfer interface IWiaTransfer *pWiaTransfer = NULL; HRESULT hr = pWiaItem2->QueryInterface( IID_IWiaTransfer, (void**)&pWiaTransfer ); if (SUCCEEDED(hr)) { // Create our callback class CWiaTransferCallback *pWiaClassCallback = new CWiaTransferCallback; if (pWiaClassCallback) { // Get the IWiaTransferCallback interface from our callback class. IWiaTransferCallback *pWiaTransferCallback = NULL; hr = pWiaClassCallback->QueryInterface( IID_IWiaTransferCallback, (void**)&pWiaTransferCallback ); if (SUCCEEDED(hr)) { //Set the format for the item to BMP IWiaPropertyStorage* pWiaPropertyStorage = NULL; HRESULT hr = pWiaItem2->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage ); if(SUCCEEDED(hr)) { hr = WritePropertyGuid(pWiaPropertyStorage,WIA_IPA_FORMAT,WiaImgFmt_BMP); if(FAILED(hr)) { ReportError(TEXT("WritePropertyGuid() failed in DownloadItem().Format couldn't be set to BMP"),hr); } //Get the file extension and initialize callback with this extension and directory in which to transfer image //along with feeder flag. //This will result in m_szFileName member callback class being set on which GetNextStream() will create and return a stream BSTR bstrFileExtension = NULL; ReadPropertyBSTR(pWiaPropertyStorage,WIA_IPA_FILENAME_EXTENSION, &bstrFileExtension); //Get the temporary folder path which is the directory where we will download the images TCHAR bufferTempPath[MAX_TEMP_PATH]; GetTempPath(MAX_TEMP_PATH , bufferTempPath); // Find out item type GUID itemCategory = GUID_NULL; ReadPropertyGuid(pWiaItem2,WIA_IPA_ITEM_CATEGORY,&itemCategory ); BOOL bFeederTransfer = FALSE; if(IsEqualGUID(itemCategory,WIA_CATEGORY_FEEDER)) { //Set WIA_IPS_PAGES to ALL_PAGES will enable transfer of all pages in the document feeder (multi-page transfer). //If somebody wants to scan a specific number of pages say N, he should set WIA_IPS_PAGES to N. WritePropertyLong(pWiaPropertyStorage,WIA_IPS_PAGES,ALL_PAGES); bFeederTransfer = TRUE; } //Initialize the callback class with the directory, file extension and feeder flag pWiaClassCallback->InitializeCallback(bufferTempPath,bstrFileExtension,bFeederTransfer); //Now download file item hr = pWiaTransfer->Download(0,pWiaTransferCallback); if(S_OK == hr) { _tprintf(TEXT("\npWiaTransfer->Download() on file item SUCCEEDED")); } else if(S_FALSE == hr) { ReportError(TEXT("pWiaTransfer->Download() on file item returned S_FALSE. File may be empty"),hr); } else if(FAILED(hr)) { ReportError(TEXT("pWiaTransfer->Download() on file item failed"),hr); } //Release pWiaPropertyStorage interface pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } else { ReportError(TEXT("QueryInterface failed on IID_IWiaPropertyStorage"),hr); } // Release the callback interface pWiaTransferCallback->Release(); pWiaTransferCallback = NULL; } else { ReportError( TEXT("pWiaClassCallback->QueryInterface failed on IID_IWiaTransferCallback"), hr ); } // Release our callback. It should now delete itself. pWiaClassCallback->Release(); pWiaClassCallback = NULL; } else { ReportError( TEXT("Unable to create CWiaTransferCallback class instance") ); } // Release the IWiaTransfer pWiaTransfer->Release(); pWiaTransfer = NULL; } else { ReportError( TEXT("pIWiaItem2->QueryInterface failed on IID_IWiaTransfer"), hr ); } return hr; }
HRESULT EnumerateWiaDevices( IWiaDevMgr *pWiaDevMgr ) { // // Validate arguments // if (NULL == pWiaDevMgr) { return E_INVALIDARG; } // // Get a device enumerator interface // IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL; HRESULT hr = pWiaDevMgr->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo ); if (SUCCEEDED(hr)) { // // Reset the device enumerator to the beginning of the list // hr = pWiaEnumDevInfo->Reset(); if (SUCCEEDED(hr)) { // // We will loop until we get an error or pWiaEnumDevInfo->Next returns // S_FALSE to signal the end of the list. // while (S_OK == hr) { // // Get the next device's property storage interface pointer // IWiaPropertyStorage *pWiaPropertyStorage = NULL; hr = pWiaEnumDevInfo->Next( 1, &pWiaPropertyStorage, NULL ); // // pWiaEnumDevInfo->Next will return S_FALSE when the list is // exhausted, so check for S_OK before using the returned // value. // if (hr == S_OK) { // // Do something with the device's IWiaPropertyStorage* // ReadSomeWiaProperties( pWiaPropertyStorage ); // // Call a helper function to create the device // and do some stuff with it. // CreateWiaDeviceAndDoSomeStuff( pWiaDevMgr, pWiaPropertyStorage ); // // Release the device's IWiaPropertyStorage* // pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } else if (FAILED(hr)) { // // Report that an error occurred during enumeration // ReportError( TEXT("Error calling pWiaEnumDevInfo->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; } } else { // // Report that an error occurred calling Reset() // ReportError( TEXT("Error calling IEnumWIA_DEV_INFO::Reset()"), hr ); } // // Release the enumerator // pWiaEnumDevInfo->Release(); pWiaEnumDevInfo = NULL; } else { // // Report that an error occurred trying to create the enumerator // ReportError( TEXT("Error calling IWiaDevMgr::EnumDeviceInfo"), hr ); } // // Return the result of the enumeration // return hr; }
HRESULT PrintItemName( IWiaItem *pWiaItem ) { // // Validate arguments // if (NULL == pWiaItem) { return E_INVALIDARG; } // // Get the IWiaPropertyStorage interface // IWiaPropertyStorage *pWiaPropertyStorage = NULL; HRESULT hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage ); if (SUCCEEDED(hr)) { // // 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: // Device ID. This is what we'd use to create // the device. // PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = WIA_IPA_FULL_ITEM_NAME; // // Ask for the property values // hr = pWiaPropertyStorage->ReadMultiple( c_nPropertyCount, PropSpec, PropVar ); if (SUCCEEDED(hr)) { // // IWiaPropertyStorage::ReadMultiple will return S_FALSE if some // properties could not be read, so we have to check the return // types for each requested item. // // // Check the return type for the device ID // if (VT_BSTR == PropVar[0].vt) { // // Do something with the device ID // _tprintf( TEXT("Item Name: %ws\n"), PropVar[0].bstrVal ); } // // Free the returned PROPVARIANTs // FreePropVariantArray( c_nPropertyCount, PropVar ); } else { ReportError( TEXT("Error calling IWiaPropertyStorage::ReadMultiple"), hr ); } // // Release the IWiaPropertyStorage interface // pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } // // Return the result of reading the properties // return hr; }
HRESULT TransferWiaItem( IWiaItem *pWiaItem ) { // // Validate arguments // if (NULL == pWiaItem) { return E_INVALIDARG; } // // Get the IWiaPropertyStorage interface so we 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}; 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 // ReleaseStgMedium( &stgMedium ); } else { ReportError( TEXT("pWiaDataTransfer->idtGetData failed"), hr ); } // // Release the callback interface // pWiaDataCallback->Release(); pWiaDataCallback = NULL; } else { ReportError( TEXT("pCallback->QueryInterface failed on IID_IWiaDataCallback"), hr ); } // // Release our callback. It should now delete itself. // pCallback->Release(); pCallback = NULL; } else { ReportError( TEXT("Unable to create CWiaDataCallback class instance") ); } // // Release the IWiaDataTransfer // pWiaDataTransfer->Release(); pWiaDataTransfer = NULL; } else { ReportError( TEXT("pWiaItem->QueryInterface failed on IID_IWiaDataTransfer"), hr ); } } // // Release the IWiaPropertyStorage // pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } else { ReportError( TEXT("pWiaItem->QueryInterface failed on IID_IWiaPropertyStorage"), hr ); } return hr; }
HRESULT WIACamera::SetDeviceProperty(const unsigned int CamID, const PropertyType Type, const int iValue, bool bAuto) { HRESULT hr = S_OK; if ( CamID >= m_iCount ) return S_FALSE; IWiaPropertyStorage *pWiaPropertyStorage; hr = m_vRootItem[CamID]->QueryInterface(IID_IWiaPropertyStorage,(void**)&pWiaPropertyStorage); if (hr != S_OK) { return E_NOINTERFACE; } PROPSPEC PropSpec; PROPVARIANT PropVar; PropSpec.ulKind = PRSPEC_PROPID; PropVar.vt = VT_I4; if ( Type==CAMERA_SHUTTERSPEED ) { // shutter speed変更の際には,撮影モード変更後,値を設定 long lResult; PropSpec.propid = WIA_DPC_EXPOSURE_MODE; hr = ReadPropertyLong( pWiaPropertyStorage, &PropSpec, &lResult); if (bAuto) { // EXPOSUREMODE_MANUAL -> EXPOSUREMODE_APERTURE_PRIORITY // EXPOSUREMODE_SHUTTER_PRIORITY -> EXPOSUREMODE_AUTO // OTHER : NOTHING if ( lResult==EXPOSUREMODE_MANUAL ) { PropVar.lVal = EXPOSUREMODE_APERTURE_PRIORITY; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } else if ( lResult==EXPOSUREMODE_SHUTTER_PRIORITY ) { PropVar.lVal = EXPOSUREMODE_AUTO; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } } else { // EXPOSUREMODE_MANUAL <- EXPOSUREMODE_APERTURE_PRIORITY // EXPOSUREMODE_SHUTTER_PRIORITY <- EXPOSUREMODE_AUTO // OTHER : NOTHING if ( lResult==EXPOSUREMODE_APERTURE_PRIORITY ) { PropVar.lVal = EXPOSUREMODE_MANUAL; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } else if ( lResult==EXPOSUREMODE_AUTO ) { PropVar.lVal = EXPOSUREMODE_SHUTTER_PRIORITY; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } // then Set Value. PropSpec.propid = WIA_DPC_EXPOSURE_TIME; PropVar.lVal = iValue; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } } else if ( Type==CAMERA_APERTURE ) { // 絞り変更の際には,撮影モード変更後,値を設定 long lResult; PropSpec.propid = WIA_DPC_EXPOSURE_MODE; hr = ReadPropertyLong( pWiaPropertyStorage, &PropSpec, &lResult); if (bAuto) { // EXPOSUREMODE_MANUAL -> EXPOSUREMODE_SHUTTER_PRIORITY // EXPOSUREMODE_APERTURE_PRIORITY -> EXPOSUREMODE_AUTO // OTHER : NOTHING if ( lResult==EXPOSUREMODE_MANUAL ) { PropVar.lVal = EXPOSUREMODE_SHUTTER_PRIORITY; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } else if ( lResult==EXPOSUREMODE_APERTURE_PRIORITY ) { PropVar.lVal = EXPOSUREMODE_AUTO; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } } else { // EXPOSUREMODE_MANUAL <- EXPOSUREMODE_SHUTTER_PRIORITY // EXPOSUREMODE_APERTURE_PRIORITY <- EXPOSUREMODE_AUTO // OTHER : NOTHING if ( lResult==EXPOSUREMODE_SHUTTER_PRIORITY ) { PropVar.lVal = EXPOSUREMODE_MANUAL; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } else if ( lResult==EXPOSUREMODE_AUTO ) { PropVar.lVal = EXPOSUREMODE_APERTURE_PRIORITY; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } // then Set Value. PropSpec.propid = WIA_DPC_FNUMBER; PropVar.lVal = iValue; hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } } else if ( Type==CAMERA_GAIN ) { PropSpec.propid = WIA_DPC_EXPOSURE_INDEX; if (bAuto) { PropVar.lVal = 0xFFFF; } else { PropVar.lVal = iValue; } hr = pWiaPropertyStorage->WriteMultiple( 1, &PropSpec, &PropVar, 2 ); } else { hr = E_NOTIMPL; } if (pWiaPropertyStorage) { pWiaPropertyStorage->Release(); pWiaPropertyStorage = NULL; } return hr; }
HRESULT WIACamera::VideoCameraCapture(IWiaItem* pIWiaRoot, IplImage** ppIplImage) { static int COUNTER = 0; COUNTER++; HRESULT hr = S_OK; if (pIWiaRoot==NULL) { cvReleaseImage(ppIplImage); (*ppIplImage) = NULL; return hr; } IWiaPropertyStorage *pIWiaPropStg = NULL; // Get the next WIA device hr = pIWiaRoot->QueryInterface(IID_IWiaPropertyStorage,(void**)&pIWiaPropStg); if (SUCCEEDED(hr)) { // Get the device type of the device PROPSPEC PropSpec[3]; PROPVARIANT PropVar[3]; memset(PropVar,0,sizeof(PropVar)); PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = WIA_DIP_DEV_ID; PropSpec[1].ulKind = PRSPEC_PROPID; PropSpec[1].propid = WIA_DIP_DEV_TYPE; PropSpec[2].ulKind = PRSPEC_PROPID; PropSpec[2].propid = WIA_DPV_IMAGES_DIRECTORY; // Get the type and the ID of each device hr = pIWiaPropStg->ReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec, PropVar); WORD myDev = GET_STIDEVICE_TYPE(PropVar[1].lVal); if (SUCCEEDED(hr)) { hr = m_pWiaVideo->put_ImagesDirectory(PropVar[2].bstrVal); } if (SUCCEEDED(hr)) { hr = m_pWiaVideo->put_PreviewVisible(FALSE); hr = m_pWiaVideo->CreateVideoByWiaDevID(PropVar[0].bstrVal, NULL, FALSE, TRUE); } } // // Take a picture. When this function returns, WIA Video will have already // captured a still image from the video stream, and it saved the image in // the 'FileName' file. // BSTR bstrFileName = NULL; if (SUCCEEDED(hr)) { Sleep(2000); hr = m_pWiaVideo->TakePicture(&bstrFileName); } if (SUCCEEDED(hr)) { cvReleaseImage(ppIplImage); // Convert to a char* const int BUFFER_SIZE = 4096; char filepath[BUFFER_SIZE]; _bstr_t bstrIntermediate(bstrFileName); // convert to // _bstr_t // you have to go through _bstr_t to have it work in ANSI // and Unicode sprintf_s(filepath, BUFFER_SIZE, "%s", (LPCTSTR)bstrIntermediate); (*ppIplImage) = cvLoadImage((char*)filepath); } return hr; }
HRESULT WIACamera::Initialize() { // CoInitialize(NULL); CoInitializeEx(NULL, COINIT_MULTITHREADED); IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL; // // Create an instance of the device manager // HRESULT hr = CoCreateInstance( CLSID_WiaDevMgr, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&m_pWiaDevMgr ); hr = CoCreateInstance(CLSID_WiaVideo, NULL, CLSCTX_INPROC_SERVER, IID_IWiaVideo, (void**) &m_pWiaVideo); if (SUCCEEDED(hr)) { // // Enumerate WIA devices on the system // hr = m_pWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo); } // // Reset the enumeration to start at the beginning of the list. // if (SUCCEEDED(hr)) { // // Call Reset on Enumerator // hr = pWiaEnumDevInfo->Reset(); } BOOL bFound = FALSE; while ( SUCCEEDED(hr) ) { IWiaPropertyStorage *pIWiaPropStg = NULL; ULONG ulFetched = NULL; // // Get the next WIA device // hr = pWiaEnumDevInfo->Next(1, &pIWiaPropStg, &ulFetched); if (hr == S_OK) { // // Get the device type of the device // PROPSPEC PropSpec[3]; PROPVARIANT PropVar[3]; memset(PropVar,0,sizeof(PropVar)); PropSpec[0].ulKind = PRSPEC_PROPID; PropSpec[0].propid = WIA_DIP_DEV_ID; PropSpec[1].ulKind = PRSPEC_PROPID; PropSpec[1].propid = WIA_DIP_DEV_TYPE; PropSpec[2].ulKind = PRSPEC_PROPID; PropSpec[2].propid = WIA_DIP_DEV_NAME; // // Get the type and the ID of each device // hr = pIWiaPropStg->ReadMultiple(sizeof(PropSpec)/sizeof(PROPSPEC), PropSpec, PropVar); // // If the device is a streaming video device/digital camera, // get its ID // if (GET_STIDEVICE_TYPE(PropVar[1].lVal) == StiDeviceTypeStreamingVideo || GET_STIDEVICE_TYPE(PropVar[1].lVal) == StiDeviceTypeDigitalCamera) { std::wcerr << "WIA_DIP_DEV_ID :\t" << PropVar[0].bstrVal << std::endl << "WIA_DIP_DEV_NAME :\t" << PropVar[2].bstrVal << std::endl; bFound = TRUE; const size_t BUFFER_SIZE = 1024; char buf[BUFFER_SIZE]; _bstr_t bstrIntermediate; bstrIntermediate.Assign(PropVar[0].bstrVal); sprintf_s((char*)buf, BUFFER_SIZE, "%s", (LPCTSTR)bstrIntermediate); char* strID = new char [strlen(buf)+1]; strcpy_s( strID, strlen(buf)+1, buf ); m_vCameraID.push_back(strID); bstrIntermediate.Assign(PropVar[2].bstrVal); sprintf_s((char*)buf, BUFFER_SIZE, "%s", (LPCTSTR)bstrIntermediate); char* strName = new char [strlen(buf)+1]; strcpy_s( strID, strlen(buf)+1, buf ); m_vCameraName.push_back(strName); delete [] strID; delete [] strName; // // Create a WIA device and get the recommended // images directory // IWiaItem *pRootItem = NULL; hr = m_pWiaDevMgr->CreateDevice(PropVar[0].bstrVal, &pRootItem); if (GET_STIDEVICE_TYPE(PropVar[1].lVal) == StiDeviceTypeStreamingVideo) { // ビデオカメラ特有の処理 m_pCaptureFunc.push_back( &WIACamera::VideoCameraCapture ); } else { // デジタルカメラ特有の処理 m_pCaptureFunc.push_back( &WIACamera::DigitalCameraCapture ); } if (SUCCEEDED(hr)) { m_vRootItem.push_back(pRootItem); } else { m_vRootItem.push_back(NULL); throw "Error:\n"; return hr; } } } else { break; } if (pIWiaPropStg) { pIWiaPropStg->Release(); pIWiaPropStg = NULL; } } if (pWiaEnumDevInfo) { pWiaEnumDevInfo->Release(); pWiaEnumDevInfo = NULL; } if (!bFound) { // // We did not find any WIA video streaming devices. There is nothing left // to do. Set result to E_FAIL // hr = E_FAIL; return hr; } m_iCount = (unsigned int)m_vRootItem.size(); // // Return the result of creating the device manager // 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; }