Mentransfer Data Gambar di WIA 1.0

Catatan

Tutorial ini adalah tentang mentransfer data gambar dalam aplikasi yang akan berjalan Windows XP atau yang lebih lama. Lihat Mentransfer Data Gambar di WIA 2.0 untuk informasi tentang mentransfer data gambar dalam aplikasi yang akan berjalan di Windows Vista atau yang lebih baru.

 

Gunakan metode antarmuka IWiaDataTransfer untuk mentransfer data dari perangkat Windows Image Acquisition (WIA) 1.0 ke aplikasi. Antarmuka ini mendukung jendela memori bersama untuk mentransfer data dari objek perangkat ke aplikasi dan menghilangkan salinan data yang tidak perlu selama marshalling.

Aplikasi harus mengkueri item gambar untuk mendapatkan penunjuk ke antarmuka IWiaDataTransfer-nya , seperti dalam sampel kode berikut:

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

Dalam kode sebelumnya, diasumsikan bahwa pWiaItem adalah penunjuk yang valid ke antarmuka IWiaItem . Panggilan ke IUnknown::QueryInterface mengisi pWiaDataTransfer dengan pointer ke antarmuka IWiaDataTransfer dari item yang dimaksud oleh pWiaItem.

Aplikasi kemudian menetapkan anggota struktur STGMEDIUM . Untuk informasi, lihat STGMEDIUM dan TYMED.

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

Jika Anda memberikan nama file, itu harus menyertakan ekstensi file yang tepat; WIA 1.0 tidak menyediakan ekstensi file. Jika anggota lpszFileName dari StgMedium adalah NULL, WIA 1.0 menghasilkan nama dan jalur file acak untuk data yang ditransfer. Pindahkan atau salin file ini sebelum memanggil ReleaseStgMedium, karena fungsi ini akan menghapus file.

Aplikasi kemudian memanggil metode IWiaDataTransfer::idtGetData untuk menjalankan transfer data:

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

Dalam panggilan ke IWiaDataTransfer::idtGetData, parameter kedua menentukan pointer ke antarmuka IWiaDataCallback . Aplikasi harus menerapkan antarmuka ini untuk menerima panggilan balik selama transfer data. Untuk informasi tentang menerapkan antarmuka ini, lihat IWiaDataCallback::BandedDataCallback.

Aplikasi kemudian merilis pointer ke antarmuka IWiaDataTransfer dan membebaskan data apa pun yang dialokasikan dalam struktur STGMEDIUM .

Aplikasi ini juga dapat mentransfer gambar menggunakan transfer data dalam memori alih-alih transfer file. Dalam hal ini, aplikasi menggunakan metode idtGetBandedData sebagai pengganti metode idtGetData.

Berikut adalah sampel transfer data lengkap:

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