使用WIA或TWAIN扫描页面
scanning pages using WIA or TWAIN
编辑:有没有关于如何在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的相同代码。
您想要使用IWiaItem2::DeviceCommand,它向图像捕获设备发送命令。此处列出了您可以发送的命令列表。
相关文章:
- 检查不带转换的扫描格式
- 如何对__uint128_t进行位扫描(128位)?
- 我的 SonarQube C++扫描成功,但结果仅标记重复项,而没有标记其他标记的位置
- 使用扫描的调试断言失败
- 如何在 C/C++ 中将CAP_REWINDPAGE用作 TWAIN API?
- 如何在扫描中使用字符双指针?
- 使用 Clang LibTooling 扫描C++在模板化父类中调用本地类的源
- 为什么 EOF 在循环扫描期间没有终止?
- 有没有一种方法可以在linux中扫描已构建的ARM库中的函数
- ESP32_BLE_Arduino库中的扫描窗口、间隔和扫描时间之间有什么区别
- scanf() 语句中"%*[^n]"的格式字符串指示什么?分配抑制器 (*) 和否定扫描集 ([^) 如何协同工作?
- 为什么我应该在scanf()-家族成员中包含一个长度修饰符作为参数?有什么好处?使用长度修改器进行扫描的作用
- 开发QR扫描仪以扫描我生成的"only" QR码?
- 快速扫描标准以获取整数不起作用
- C++ 如何从文本文件中扫描二维数组并对行求和?
- 扫描阵列特定次数,然后找出元素
- C++客户端/服务器聊天应用程序 - 从 Ubuntu 命令窗口扫描输入
- c++ 中用于扫描数组的指针
- iwlist 在使用 execl 调用时尝试扫描所有接口
- 使用WIA或TWAIN扫描页面