5

編集:C ++でWIAまたはTWAINを使用する方法について、ページをスキャンし、設定(DPI、自動フィーダーを使用するなど)を調整し、PNGファイルとして保存する方法を説明するチュートリアルはありますか?

WIAを使用してページをスキャンし、pngファイルとして保存したいと思います。スキャナーが自動フィードをサポートしている場合は、その機能も使用したいと思います。現在、私はこのチュートリアルの手順に従っていて、セクションで立ち往生していますTransferring Image Data in WIA 2.0

これまでのところ、スキャナーが見つかり、デバイスを作成でき、IWiaItem2*が作成されました。300dpiでスキャンし、結果をpngファイルとして保存するにはどうすればよいですか?

チュートリアルでは、スキャンプロセスを開始する方法や、スキャン用にdpiを設定する方法が明確ではないため、誰かがコードを手伝ってくれることを願っています。

これは基本的に、すべてのローカルデバイスを取得するためのコードです。

bool init(IWiaDevMgr2* devMgr)
{
    //creating the device manager
    *devMgr = 0; 
    CoCreateInstance( CLSID_WiaDevMgr2, 0, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)&devMgr); 

    //enumerating wia devices
    IEnumWIA_DEV_INFO* enumDevInfo = 0; 
    HRESULT hr = devMgr->EnumDeviceInfo( WIA_DEVINFO_ENUM_LOCAL, &enumDevInfo); 

    if(SUCCEEDED(hr))
    {
        //loop until an error occurs or end of list
        while(hr == S_OK)
        {
            IWiaPropertyStorage* storage = 0; 
            hr = enumDevInfo->Next( 1, &storage, 0); 

            if(hr == S_OK)
            {
                readProperties(storage); 
                storage->Release(); 
                storage = 0; 
            }
        }

        //set hr to ok, so no error code is returned
        if(hr == S_FALSE) hr = S_OK; 

        enumDevInfo->Release();
        enumDevInfo = 0; 
    }
    return SUCCEEDED(hr); 
}

void readProperties(IWiaPropertyStorage* storage)
{
    PROPSPEC propSpec[2] = {0};
    PROPVARIANT propVar[2] = {0};

    const ULONG propCount = sizeof(propSpec) / sizeof(propSpec[0]); 

    propSpec[0].ulKind = PRSPEC_PROPID;
    propSpec[0].propid = WIA_DIP_DEV_ID; 

    propSpec[1].ulKind = PRSPEC_PROPID; 
    propSpec[1].propid = WIA_DIP_DEV_NAME; 

    HRESULT hr = storage->ReadMultiple(propCount, propSpec, propVar); 

    if(SUCCEEDED(hr))
    {
        Device* dev = new Device(propVar[0].bstrVal, propVar[1].bstrVal); 
        devices.push_back( dev ); 
        FreePropVariantArray( propCount, propVar ); 
    }
}

その後、デバイスは次のように初期化されます。

bool createDevice(BSTR id, IWiaItem2** item)
{
*item = 0; 
HRESULT hr = devMgr->CreateDevice( 0, deviceId, item); 
return SUCCEEDED(hr); 
}

次に、アイテムが列挙されます。

bool enumerateItems(IWiaItem2* item)
{
    LONG itemType = 0; 
    HRESULT hr = item->GetItemType(&itemType); 

    if(SUCCEEDED(hr))
    {
        if(itemType & WiaItemTypeFolder || itemType & WiaItemTypeHasAttachments)
        {
            IEnumWiaItem2* enumItem = 0; 
            hr = item->EnumChildItems(0, &enumItem );

            while(hr == S_OK)
            {
                IWiaItem2* child = 0; 
                hr = enumItem->Next( 1, &child, 0 ); 

                if(hr == S_OK)
                {
                    hr = enumerateItems( child ); 

                    child->Release();
                    child = 0; 
                }
            }

            if(hr == S_FALSE) hr = S_OK; 

            enumItem->Release(); 
            enumItem = 0; 
        }
    }

    return SUCCEEDED(hr); 
}

すべてが初期化されたので、スキャン機能を実装したいと思います。ただし、チュートリアルで提供されるコードは、ファイルとフォルダーを転送するためのものであり、画像をスキャンするためのものではありません。

void scanAndSaveAsPNG(IWiaItem2* item, unsigned int dpi, std::string targetPath)
{

}

編集: スキャナードライバーの利用可能な最新バージョン(WIAおよびTWAIN)をインストールし、このコードを使用してサポートされているコマンドを確認した後

void printCommands(IWiaItem2* i)
{
    IEnumWIA_DEV_CAPS* caps = 0; 
    HRESULT h = item->EnumDeviceCapabilities(WIA_DEVICE_COMMANDS, &caps);  

    if(SUCCEEDED(h))
    {
        ULONG count = 0;
        caps->GetCount(&count); 

        if(count > 0)
        {
            WIA_DEV_CAP* cap = new WIA_DEV_CAP[ count ]; 
            ULONG fetched; 
            caps->Next(count, cap, &fetched); 

            for(int i = 0; i < fetched; i++)
            {
                std::cout << bstr_t( cap[i].bstrName ) << "\n"; 
            }
        }

        caps->Release();
    }
}

リストしかないことに気づきましたWIA Synchronize command。デバイスを正しく初期化できなかったのか、ドライバーがインストールされていてもデバイスがすべてのWIAコマンドをサポートしていないのかわかりません。

したがって、この問題が解決されない限り、代わりにTWAINに基づいた同じコードも探しています。

4

1 に答える 1

0

イメージ キャプチャ デバイスにコマンドを送信するIWiaItem2::DeviceCommandを使用します。送信できるコマンドのリストは、ここにリストされています。

于 2012-01-13T01:18:41.390 に答える