Transfert de données d’image dans WIA 1.0

Notes

Ce didacticiel concerne le transfert de données d’image dans des applications qui exécutent Windows XP ou une version antérieure. Consultez Transférer des données d’image dans WIA 2.0 pour plus d’informations sur le transfert de données d’image dans des applications qui s’exécuteront sur Windows Vista ou une version ultérieure.

 

Utilisez les méthodes de l’interface IWiaDataTransfer pour transférer des données d’un appareil WIA (Windows Image Acquisition) 1.0 vers une application. Cette interface prend en charge une fenêtre de mémoire partagée pour transférer des données de l’objet d’appareil vers l’application et éliminer les copies de données inutiles pendant le marshalling.

Les applications doivent interroger un élément d’image pour obtenir un pointeur vers son interface IWiaDataTransfer , comme dans l’exemple de code suivant :

    // Get the IWiaDataTransfer interface
    //
    IWiaDataTransfer *pWiaDataTransfer = NULL;
    hr = pWiaItem->QueryInterface( IID_IWiaDataTransfer, (void**)&pWiaDataTransfer );

Dans le code précédent, il est supposé que pWiaItem est un pointeur valide vers l’interface IWiaItem . L’appel à IUnknown::QueryInterface remplit pWiaDataTransfer avec un pointeur vers l’interface IWiaDataTransfer de l’élément référencé par pWiaItem.

L’application définit ensuite les membres de la structure STGMEDIUM . Pour plus d’informations, consultez STGMEDIUM et TYMED.

    // Set storage medium
    //
    STGMEDIUM StgMedium = {0};
    StgMedium.tymed = TYMED_FILE;

Si vous fournissez un nom de fichier, il doit inclure l’extension de fichier appropriée; WIA 1.0 ne fournit pas d’extensions de fichier. Si le membre lpszFileName de StgMedium est NULL, WIA 1.0 génère un nom de fichier et un chemin aléatoires pour les données transférées. Déplacez ou copiez ce fichier avant d’appeler ReleaseStgMedium, car cette fonction supprime le fichier.

L’application appelle ensuite la méthode IWiaDataTransfer::idtGetData pour exécuter le transfert de données :

    // Perform the transfer
    //
    hr = pWiaDataTransfer->idtGetData( &stgMedium, pWiaDataCallback );

Dans l’appel à IWiaDataTransfer::idtGetData, le deuxième paramètre spécifie un pointeur vers l’interface IWiaDataCallback . Les applications doivent implémenter cette interface pour recevoir des rappels pendant les transferts de données. Pour plus d’informations sur l’implémentation de cette interface, consultez IWiaDataCallback::BandedDataCallback.

L’application libère ensuite les pointeurs vers l’interface IWiaDataTransfer et libère toutes les données allouées dans la structure STGMEDIUM .

L’application peut également transférer l’image à l’aide de transferts de données en mémoire au lieu de transferts de fichiers. Dans ce cas, l’application utilise la méthode idtGetBandedData à la place de la méthode idtGetData.

Voici l’exemple complet de transfert de données :

HRESULT TransferWiaItem( IWiaItem *pWiaItem )
{
    //
    // Validate arguments
    //
    if (NULL == pWiaItem)
    {
        return E_INVALIDARG;
    }

    //
    // Get the IWiaPropertyStorage interface so you 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};
                        StgMedium.tymed = TYMED_FILE;
                        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
                            // This will delete the file stgMedium.lpszFileName.
                            //
                            ReleaseStgMedium( &stgMedium );
                        }

                        //
                        // Release the callback interface
                        //
                        pWiaDataCallback->Release();
                        pWiaDataCallback = NULL;
                    }

                    //
                    // Release our callback.  It should now delete itself.
                    //
                    pCallback->Release();
                    pCallback = NULL;
                }

                //
                // Release the IWiaDataTransfer
                //
                pWiaDataTransfer->Release();
                pWiaDataTransfer = NULL;
            }
        }

        //
        // Release the IWiaPropertyStorage
        //
        pWiaPropertyStorage->Release();
        pWiaPropertyStorage = NULL;
    }

    return hr;
}