Форум программистов, компьютерный форум, киберфорум
C/C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 29.02.2016
Сообщений: 50
1

Сканирование через WIA

06.06.2019, 15:36. Показов 13948. Ответов 0
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет, не могу понять в чем проблема, нужно сканировать изображение без каких либо диалоговых окон
Windows 10, сканера два, оба canon, для проверки делал все прям как тут

файл WiaScan.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#pragma once
#include "wia_lh.h"
#include "Wia.h"
#include "combaseapi.h"
#include <iostream> 
#include <QDebug>
#include "shlwapi.h"
#include "atlbase.h"
#include "wiadef.h"
 
class WIAScan
{
public:
    explicit WIAScan(IWiaDevMgr2  ** deviceManager);
    ~WIAScan() { CoUninitialize(); }
 
private:
    IWiaDevMgr2 * devMgr;
    IWiaItem2 ** wiaItem;
    BSTR devId;
    QString devName;
    HRESULT CreateWiaDeviceManager(IWiaDevMgr2 **ppWiaDevMgr);
    HRESULT EnumerateWiaDevices(IWiaDevMgr2 *pWiaDevMgr);
    HRESULT ReadSomeWiaProperties(IWiaPropertyStorage *pWiaPropertyStorage);
    HRESULT CreateWiaDevice(IWiaDevMgr2 *pWiaDevMgr, BSTR bstrDeviceID, IWiaItem2 **ppWiaDevice);
    HRESULT EnumerateItems(IWiaItem2 *pWiaItem);
    HRESULT TransferWiaItem(IWiaItem2 *pIWiaItem);
    void PrintCommands(IWiaItem2 * item);
 
    class CWiaDataCallback : public IWiaTransferCallback//IWiaDataCallback
    {
    private:
        LONG  m_cRef;               // Object reference count 
        PBYTE m_pBuffer;            // Data buffer
        LONG  m_nBufferLength;      // Length of buffer
        LONG  m_nBytesTransfered;   // Total number of bytes transferred
        GUID  m_guidFormat;         // Data format
 
    public:
        CWiaDataCallback()  : m_cRef(1), m_pBuffer(NULL), m_nBufferLength(0), m_nBytesTransfered(0), m_guidFormat(IID_NULL) { }
        ~CWiaDataCallback()
        {
            if (m_pBuffer)
            {
                LocalFree(m_pBuffer);
                m_pBuffer = NULL;
            }
            m_nBufferLength = 0;
            m_nBytesTransfered = 0;
        }
        HRESULT CALLBACK QueryInterface(REFIID riid, void **ppvObject)
        {
            if (NULL == ppvObject)
                return E_INVALIDARG;
            if (IsEqualIID(riid, IID_IUnknown))
                *ppvObject = static_cast<CWiaDataCallback *>(this);
            else if (IsEqualIID(riid, IID_IWiaDataCallback))
                *ppvObject = static_cast<CWiaDataCallback *>(this);
            else
            {
                *ppvObject = NULL;
                return(E_NOINTERFACE);
            }
            reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
            return S_OK;
        }
        ULONG CALLBACK AddRef()
        {
            return InterlockedIncrement(&m_cRef);
        }
        ULONG CALLBACK Release()
        {
            LONG cRef = InterlockedDecrement(&m_cRef);
            if (0 == cRef)
            {
                delete this;
            }
            return cRef;
        }
        HRESULT _stdcall BandedDataCallback(LONG lMessage, LONG lStatus, LONG lPercentComplete, LONG lOffset, LONG lLength, LONG lReserved, LONG lResLength, BYTE *pbData)
        {
            UNREFERENCED_PARAMETER(lReserved);
            UNREFERENCED_PARAMETER(lResLength);
            switch (lMessage)
            {
            case IT_MSG_DATA_HEADER:
            {
                PWIA_DATA_CALLBACK_HEADER pHeader = reinterpret_cast<PWIA_DATA_CALLBACK_HEADER>(pbData);
                if (pHeader && pHeader->lBufferSize)
                {
                    m_pBuffer = reinterpret_cast<PBYTE>(LocalAlloc(LPTR, pHeader->lBufferSize));
                    if (m_pBuffer)
                    {
                        m_nBufferLength = pHeader->lBufferSize;
                        m_nBytesTransfered = 0;
                        m_guidFormat = pHeader->guidFormatID;
                    }
                }
            }
            break;
 
            case IT_MSG_DATA:
            {
                if (NULL != m_pBuffer)
                {
                    CopyMemory(m_pBuffer + lOffset, pbData, lLength);
                    m_nBytesTransfered += lLength;
                }
            }
            break;
 
            case IT_MSG_STATUS:
            {
                if (lStatus & IT_STATUS_TRANSFER_FROM_DEVICE)
                {
                    qDebug() << "Transfer from device\n";
                }
                else if (lStatus & IT_STATUS_PROCESSING_DATA)
                {
                    qDebug() << "Processing Data\n";
                }
                else if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT)
                {
                    qDebug() << "Transfer to Client\n";
                }
                qDebug() << "lPercentComplete: " << lPercentComplete << "\n";
            }
            break;
            }
 
            return S_OK;
        }
        HRESULT STDMETHODCALLTYPE TransferCallback(LONG lFlags, __RPC__in WiaTransferParams *pWiaTransferParams) { std::cout << "TransferCallback";
        return S_OK;
        }
        HRESULT STDMETHODCALLTYPE GetNextStream(LONG lFlags, __RPC__in BSTR bstrItemName, __RPC__in BSTR bstrFullItemName, _Outptr_result_maybenull_ _At_(*ppDestination, _When_(return == S_OK, _Post_notnull_))  IStream **ppDestination) { std::cout << "GetNextStream";
        return S_OK;
        }
    };
 
};
файл WiaScan.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include "WiaScan.h"
 
WIAScan::WIAScan(IWiaDevMgr2  ** deviceManager) : wiaItem(new IWiaItem2 *)
{
    CoInitialize(NULL);
    if (SUCCEEDED(CreateWiaDeviceManager(deviceManager)))
        if (SUCCEEDED(EnumerateWiaDevices(*deviceManager)))
            if (SUCCEEDED(CreateWiaDevice(*deviceManager, devId, wiaItem)))
                if (SUCCEEDED(EnumerateItems(*wiaItem)))
                    TransferWiaItem(*wiaItem);
                else
                    std::cout << "Enumerate items error";
            else
                std::cout << "Creation error";
        else
            std::cout << "Enumerate wia error";
    else
        std::cout << "Manager error";
}
 
HRESULT WIAScan::CreateWiaDeviceManager(IWiaDevMgr2 **ppWiaDevMgr)
{
    *ppWiaDevMgr = NULL;
    HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr2, NULL, CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr2, (void**)ppWiaDevMgr);
    return hr;
}
 
HRESULT WIAScan::EnumerateWiaDevices(IWiaDevMgr2 *ppWiaDevMgr)
{
    IEnumWIA_DEV_INFO *pWiaEnumDevInfo = NULL;
    HRESULT hr = ppWiaDevMgr->EnumDeviceInfo(WIA_DEVINFO_ENUM_LOCAL, &pWiaEnumDevInfo);
    if (SUCCEEDED(hr))
    {
        while (S_OK == hr)
        {
            IWiaPropertyStorage *pWiaPropertyStorage = NULL;
            hr = pWiaEnumDevInfo->Next(1, &pWiaPropertyStorage, NULL);
            if (hr == S_OK)
            {
                ReadSomeWiaProperties(pWiaPropertyStorage);
                pWiaPropertyStorage->Release();
                pWiaPropertyStorage = NULL;
            }
        }
        if (S_FALSE == hr)
            return hr;
        pWiaEnumDevInfo->Release();
        pWiaEnumDevInfo = NULL;
    }
    return hr;
}
 
HRESULT WIAScan::ReadSomeWiaProperties(IWiaPropertyStorage *pWiaPropertyStorage)
{
    if (NULL == pWiaPropertyStorage)
        return E_INVALIDARG;
    PROPSPEC PropSpec[3] = { 0 };
    PROPVARIANT PropVar[3] = { 0 };
    const ULONG c_nPropertyCount = 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;
    PropSpec[2].ulKind = PRSPEC_PROPID;
    PropSpec[2].propid = WIA_DIP_DEV_DESC;
    HRESULT hr = pWiaPropertyStorage->ReadMultiple(c_nPropertyCount, PropSpec, PropVar);
    if (SUCCEEDED(hr))
    {
        if (VT_BSTR == PropVar[0].vt)
            devId = SysAllocString(PropVar[0].bstrVal);
        if (VT_BSTR == PropVar[1].vt)
            devName = QString::fromWCharArray(PropVar[1].bstrVal);
        FreePropVariantArray(c_nPropertyCount, PropVar);
    }
    return hr;
}
 
HRESULT WIAScan::CreateWiaDevice(IWiaDevMgr2 *pWiaDevMgr, BSTR bstrDeviceID, IWiaItem2 **ppWiaDevice)
{
    if (NULL == pWiaDevMgr || NULL == bstrDeviceID || NULL == ppWiaDevice)
        return E_INVALIDARG;
    *ppWiaDevice = NULL;
    HRESULT hr = pWiaDevMgr->CreateDevice(NULL, bstrDeviceID, ppWiaDevice);
    return hr;
}
 
HRESULT WIAScan::EnumerateItems(IWiaItem2 *pWiaItem)
{
    if (NULL == pWiaItem)
        return E_INVALIDARG;
    LONG lItemType = 0;
    HRESULT hr = pWiaItem->GetItemType(&lItemType);
    if (SUCCEEDED(hr))
    {
        if (lItemType & WiaItemTypeFolder || lItemType & WiaItemTypeHasAttachments)
        {
            IEnumWiaItem2 *pEnumWiaItem = NULL;
            hr = pWiaItem->EnumChildItems(NULL, &pEnumWiaItem);
            if (SUCCEEDED(hr))
            {
                while (S_OK == hr)
                {
                    IWiaItem2 *pChildWiaItem = NULL;
                    hr = pEnumWiaItem->Next(1, &pChildWiaItem, NULL);
                    if (S_OK == hr)
                    {
                        LONG lItemType = 0;
                        hr = pChildWiaItem->GetItemType(&lItemType);
                        if (lItemType & WiaItemTypeFolder || lItemType & WiaItemTypeHasAttachments)
                        {
                            hr = EnumerateItems(pChildWiaItem);
                            PrintCommands(pChildWiaItem);
                        }
                        pChildWiaItem->Release();
                        pChildWiaItem = NULL;
                    }
                }
                if (S_FALSE == hr)
                    hr = S_OK;          
                pEnumWiaItem->Release();
                pEnumWiaItem = NULL;
            }
        }
    }
    return  hr;
}
 
HRESULT WIAScan::TransferWiaItem(IWiaItem2 *pIWiaItem2)
{
    if (NULL == pIWiaItem2)
        return E_INVALIDARG;
    IWiaTransfer * pWiaTransfer = NULL;
    HRESULT hr = pIWiaItem2->QueryInterface(IID_IWiaTransfer, (void**)&pWiaTransfer);
    if (SUCCEEDED(hr))
    {
        CWiaDataCallback * pWiaClassCallback = new CWiaDataCallback;
        IWiaItem2 ** ppWiaItemChild = new IWiaItem2 *;
        IWiaItem2 * pWiaItemChild = NULL;
        CComBSTR bzUploadFileName (L"ImageItem");
        hr = pIWiaItem2->CreateChildItem(WiaItemTypeTransfer, 0, bzUploadFileName, ppWiaItemChild);
        if (pWiaClassCallback)
        {
            LONG lItemType = 0;
            hr = pIWiaItem2->GetItemType(&lItemType);
            //if (lItemType & WiaItemTypeTransfer)
            {
                /*if ((lItemType & WiaItemTypeFolder))
                {
                    std::cout << "\nI am a folder item";
                    hr = pWiaTransfer->Download(NULL, pWiaClassCallback);
                    if (S_OK == hr)
                        std::cout << "\npWiaTransfer->Download() on folder item SUCCEEDED";
                    else if (S_FALSE == hr)
                        std::cout << "\npWiaTransfer->Download() on folder item returned S_FALSE. Folder may not be having child items" << hr;
                    else if (FAILED(hr))
                        std::cout << "\npWiaTransfer->Download() on folder item failed" << hr;
                }
                else if (lItemType & WiaItemTypeFile)*/
                {
                    hr = pWiaTransfer->Download(0, pWiaClassCallback);
                    if (S_OK == hr)
                        std::cout << "\npWiaTransfer->Download() on file item SUCCEEDED";
                    else if (S_FALSE == hr)
                        std::cout << "\npWiaTransfer->Download() on file item returned S_FALSE. File may be empty" << hr;
                    else if (FAILED(hr))
                        std::cout << "\npWiaTransfer->Download() on file item failed" << hr;
                }
            }
            pWiaClassCallback->Release();
            pWiaClassCallback = NULL;
        }
        else
            std::cout << "\nUnable to create CWiaTransferCallback class instance";
        pWiaTransfer->Release();
        pWiaTransfer = NULL;
    }
    else
        std::cout << "\npIWiaItem2->QueryInterface failed on IID_IWiaTransfer" << hr;
    return hr;
}
 
void WIAScan::PrintCommands(IWiaItem2* item)
{
    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 << cap[i].bstrName << "\n";
        }
        caps->Release();
    }
}
скорее всего в тексте есть какие то мои ошибки, в основном все копировал по ссылке
проблема в подключении к устройству, процедура вывода команд, в ней только 4 пункта Syncronize/Delete all items/Delete device tree/Build device tree. я так понял должны быть в т.ч Take picture или как то так.

item->DeviceCommand(NULL, &WIA_CMD_BUILD_DEVICE_TREE, &item); - работает, но ничего не меняет в дереве
через item->DeviceDialog(........) запускается стандартное wia окно, через него работает сканирование, но мне нужно без него сделать

item->CreateChildItem(WiaItemTypeImage, NULL, imgName, wiaImageItem); - E_NOTIMPL
item->DeviceCommand(NULL, &WIA_CMD_TAKE_PICTURE, wiaImageItem); - соответственно из предыдущей команда, тоже не работает, может не хватает какой нибудь инициализации Com порта, имя устройства, его id и описание драйвера читаются
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.06.2019, 15:36
Ответы с готовыми решениями:

WIA сканирование с заданными параметрами
Использую WIA для сканирования документов, как можно получить изображение со сканера, без вызова окна для выбора параметров, а сканировать...

Как сделать скоростное многостраничное сканирование (twain или wia)
word: макрос: как сделать скоростное многостраничное сканирование (twain или wia) Макрос многостраничного сканирования простой. Надо...

Сканирование IP через сокеты
Возникла такая проблема пишу программу которая должна управлять другим компом через socet и вот возник вопрос как зделать так чтоб...

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
06.06.2019, 15:36
Помогаю со студенческими работами здесь

Почему при указании пути через имя компа сканирование не проходит, а через IP - проходит?
Всем доброго времени суток, Ситуация такая - Есть 3 компа с Windows 7 на борту (у всех их настройки и ПО идентичные, только имена...

Сканирование железа через ЛВС
Необходимо написать программу со следующими функциями: - поиск доступных компьютеров в локальной сети; - получение информации о...

Сканирование и вызов печати через ассемблер
Нужен кусочек программы со сканированием и вызовом печати найденного

Сканирование процесса через определенное время
Привет, как сделать сканирование процесса через опредиленное время например каждых 5-10 минут?

Как работать с WIA?
Как работать с этой штукой.


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему

Редактор формул (кликните на картинку в правом углу, чтобы закрыть)
Новые блоги и статьи
Что нового в C# 14
UnmanagedCoder 10.03.2025
Предстоящая версия C# 14 обещает принести изменения, которые сделают разработку еще более приятной и эффективной. Что стоит отметить, так это влияние сообщества разработчиков на формирование новых. . .
Формулы поворота
Igor3D 10.03.2025
Добрый день Тема Эти формулы приводятся во множестве тьюториалов, часто под видом "матрица вращения на плоскости". x' = x * cos(a) - y * sin(a) y' = y * cos(a) + x * sin(a) Как бы Вы их. . .
Что нового в .NET 10
UnmanagedCoder 10.03.2025
. NET 10 выходит как релиз с длительной поддержкой (LTS), включающей три года обновлений. В этом обновлении Microsoft сфокусировались на нескольких направлениях: производительность, оптимизация. . .
Отложенное высвобождение, RCU и Hazard Pointer в C++26
NullReferenced 09.03.2025
Многопоточное программирование стало важной частью современной разработки. Когда несколько потоков одновременно работают с общими данными, возникает целый ряд проблем, связанных с синхронизацией и. . .
Неблокирующийся стек на C++26
NullReferenced 09.03.2025
Традиционные способы синхронизации в многопоточном программировании — мьютексы, семафоры, условные переменные — часто превращаются в узкое место в плане производительности. При этом неблокирующиеся. . .
Обработка строк в C++26: Новые возможности string и string_view
NullReferenced 09.03.2025
Новый стандарт C++26 предлагает много улучшений для работы с привычными string и относительно новыми string_view. string_view - это невладеющая ссылка на последовательность символов, появившаяся в. . .
Мой первый аддон для Blender 3D, с помощью нейронки (не зная даже азов пайтона, но это не значит что так и с остальным).
Hrethgir 09.03.2025
Потратил весь день. Пол-дня мне хватило, чтобы понять что с версией с 14B мне не одолеть написание функционального кода, на языке с которым я вообще никак не знаком - пайтон. Версия 22B от другого. . .
Einstein@Home сегодня исполняется двадцать лет!
Programma_Boinc 09.03.2025
Einstein@Home сегодня исполняется двадцать лет! Отправлено 19 февраля 2025 года в 17:20:21 UTC Я хочу поздравить всех наших волонтеров, разработчиков и ученых из Einstein@Home. Мы официально. . .
Заполнители и расширенный набор символов в C++26
NullReferenced 09.03.2025
C++26 представляет два важных обновления: заполнители и расширенный набор символов. Заполнители (placeholders) решают давнюю проблему лаконичности кода в шаблонных выражениях и лямбда-функциях. Они. . .
Контракты в C++26
NullReferenced 09.03.2025
Контракты – это механизм, позволяющий указывать предусловия, постусловия и инварианты для функций в коде. Эта функциональность должна была стать частью C++20, но была исключена на встрече комитета. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru