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;
}
Beispiel #2
0
HRESULT 
WiaGetImage(
    HWND                 hWndParent,
    LONG                 lDeviceType,
    LONG                 lFlags,
    LONG                 lIntent,
    IWiaDevMgr          *pSuppliedWiaDevMgr,
    IWiaItem            *pSuppliedItemRoot,
    PFNPROGRESSCALLBACK  pfnProgressCallback,
    PVOID                pProgressCallbackParam,
    GUID                *pguidFormat,
    LONG                *plCount,
    IStream             ***pppStream
)
{
    HRESULT hr;

    // Validate and initialize output parameters

    if (plCount == NULL)
    {
        return E_POINTER;
    }

    if (pppStream == NULL)
    {
        return E_POINTER;
    }

    *plCount = 0;
    *pppStream = NULL;

    // Initialize the local root item variable with the supplied value.
    // If no value is supplied, display the device selection common dialog.

    CComPtr<IWiaItem> pItemRoot = pSuppliedItemRoot;

    if (pItemRoot == NULL)
    {
        // Initialize the device manager pointer with the supplied value
        // If no value is supplied, connect to the local device manager

        CComPtr<IWiaDevMgr> pWiaDevMgr = pSuppliedWiaDevMgr;

        if (pWiaDevMgr == NULL)
        {
            hr = pWiaDevMgr.CoCreateInstance(CLSID_WiaDevMgr);

            if (FAILED(hr))
            {
                return hr;
            }
        }
    
        // Display the device selection common dialog

        hr = pWiaDevMgr->SelectDeviceDlg(
            hWndParent,
            lDeviceType,
            lFlags,
            0,
            &pItemRoot
        );

        if (FAILED(hr) || hr == S_FALSE)
        {
            return hr;
        }
    }

    // Display the image selection common dialog 

    CComPtrArray<IWiaItem> ppIWiaItem;

    hr = pItemRoot->DeviceDlg(
        hWndParent,
        lFlags,
        lIntent,
        &ppIWiaItem.Count(),
        &ppIWiaItem
    );

    if (FAILED(hr) || hr == S_FALSE)
    {
        return hr;
    }

    // For ADF scanners, the common dialog explicitly sets the page count to one.
    // So in order to transfer multiple images, set the page count to ALL_PAGES
    // if the WIA_DEVICE_DIALOG_SINGLE_IMAGE flag is not specified, 

    if (!(lFlags & WIA_DEVICE_DIALOG_SINGLE_IMAGE))
    {
        // Get the property storage interface pointer for the root item

        CComQIPtr<IWiaPropertyStorage> pWiaRootPropertyStorage(pItemRoot);

        if (pWiaRootPropertyStorage == NULL)
        {
            return E_NOINTERFACE;
        }

        // Determine if the selected device is a scanner or not

        PROPSPEC specDevType;

        specDevType.ulKind = PRSPEC_PROPID;
        specDevType.propid = WIA_DIP_DEV_TYPE;

        LONG nDevType;

        hr = ReadPropertyLong(
            pWiaRootPropertyStorage, 
            &specDevType, 
            &nDevType
        );

        if (SUCCEEDED(hr) && (GET_STIDEVICE_TYPE(nDevType) == StiDeviceTypeScanner))
        {
            // Determine if the document feeder is selected or not

            PROPSPEC specDocumentHandlingSelect;

            specDocumentHandlingSelect.ulKind = PRSPEC_PROPID;
            specDocumentHandlingSelect.propid = WIA_DPS_DOCUMENT_HANDLING_SELECT;

            LONG nDocumentHandlingSelect;

            hr = ReadPropertyLong(
                pWiaRootPropertyStorage, 
                &specDocumentHandlingSelect, 
                &nDocumentHandlingSelect
            );

            if (SUCCEEDED(hr) && (nDocumentHandlingSelect & FEEDER))
            {
                PROPSPEC specPages;

                specPages.ulKind = PRSPEC_PROPID;
                specPages.propid = WIA_DPS_PAGES;

                PROPVARIANT varPages;
                    
                varPages.vt = VT_I4;
                varPages.lVal = ALL_PAGES;

                pWiaRootPropertyStorage->WriteMultiple(
                    1,
                    &specPages,
                    &varPages,
                    WIA_DPS_FIRST
                );
                
                PropVariantClear(&varPages);
            }
        }
    }

    // If a status callback function is not supplied, use the default.
    // The default displays a simple dialog with a progress bar and cancel button.

    CComPtr<CProgressDlg> pProgressDlg;

    if (pfnProgressCallback == NULL)
    {
        pfnProgressCallback = DefaultProgressCallback;

        pProgressDlg = new CProgressDlg(hWndParent);

        pProgressCallbackParam = (CProgressDlg *) pProgressDlg;
    }

    // Create the data callback interface

    CComPtr<CDataCallback> pDataCallback = new CDataCallback(
        pfnProgressCallback,
        pProgressCallbackParam,
        plCount, 
        pppStream
    );

    if (pDataCallback == NULL)
    {
        return E_OUTOFMEMORY;
    }

    // Start the transfer of the selected items

    for (int i = 0; i < ppIWiaItem.Count(); ++i)
    {
        // Get the interface pointers

        CComQIPtr<IWiaPropertyStorage> pWiaPropertyStorage(ppIWiaItem[i]);

        if (pWiaPropertyStorage == NULL)
        {
            return E_NOINTERFACE;
        }

        CComQIPtr<IWiaDataTransfer> pIWiaDataTransfer(ppIWiaItem[i]);

        if (pIWiaDataTransfer == NULL)
        {
            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;

        if (pguidFormat == NULL)
        {
            pguidFormat = &guidFormat;
        }

        if (*pguidFormat == GUID_NULL)
        {
            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;

        specFormat.ulKind = PRSPEC_PROPID;
        specFormat.propid = WIA_IPA_FORMAT;

        PROPVARIANT varFormat;

        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 (FAILED(hr) || hr == S_FALSE)
        {
            return hr;
        }
    }

    return S_OK;
}
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;
}