編集: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に基づいた同じコードも探しています。