編輯:有沒有關於如何在C++中使用WIA或TWAIN的任何教程,解釋如何掃描頁面,調整設置(DPI,使用自動送紙器等)並將它們保存爲PNG文件?使用WIA或TWAIN掃描頁面
我想使用WIA掃描頁面並將它們存儲爲png文件。如果掃描儀支持自動送紙,我還想使用該功能。目前我正在按照this教程的步驟進行操作,並卡在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的相同代碼。
不確定您是否考慮使用商用SDK。使用一些TWAIN控件,您可以在幾小時內完成您在幾行代碼中列出的任務。我的公司有Dynamic Web TWAIN。我建議你嘗試一下。 – flysakura 2012-02-13 06:28:44