This project has moved. For the latest updates, please go here.

Многостраничное сканирование

Nov 11, 2014 at 12:23 PM
Добрый день! Огромное спасибо за программу, она очень помогла, но возникла трудность с изменением кода в плане добавление возможности многостраничного сканирования. Я так понимаю, что для повторного сканирования нам нужно вызывать метод Acquire, который описан в Saraff.Twain.dll? И вызывать его нужно внутри этой dll, а не в моей программе?

Спасибо за ответ!
Coordinator
Nov 11, 2014 at 7:23 PM
Edited Nov 11, 2014 at 8:24 PM
Добрый день, AlexS33!
Для многостраничного сканирования никаких изменений в код Saraff.Twain.dll вносить не требуется. Разъясните подробнее, что в Вашем понимании является многостраничным сканированием. Если речь идет о сканировании нескольких страниц с использованием автоподачи, то необходимо использовать возможности (capabilities) устройства сканирования. Если речь идет о программной (прикладной) реализации многостраничного (многократного) сканирования, то именно прикладная программа (top level) должна вызывать метод Twain32.Acquire необходимое количество раз. При этом, если используется интерфейс источника данных (data source interface), то можно установить значение свойства Twain32.DisableAfterAcquire=false для предотвращения закрытия интерфейса источника данных после окончания сканирования каждой страницы.
Marked as answer by SARAFF on 11/12/2014 at 5:57 AM
Nov 12, 2014 at 8:38 AM
Большое спасибо, нужен был как раз второй вариант.
Nov 13, 2014 at 2:16 PM
Edited Nov 13, 2014 at 2:22 PM
Установил свойство Twain32.DisableAfterAcquire=false перед вызовом twain32.Acquire(). Интерфейс источника данных не закрылся, но когда второй раз нажимаю "Сканировать", появляется окно со статусом сканирования (Progress Bar) и дальше ничего не происходит. Нажимаю отмена, можно сделать предварительное сканирование, но если опять нажать "Сканировать" ничего не происходит. В чём может быть проблема? Может быть потому что первая страница отображается в прикладной программе и записать в ней повторно он не может? P.S. Можно воспроизвести на Sample2
Coordinator
Nov 13, 2014 at 8:05 PM
Добрый день, AlexS33!
В Saraff.Twain.Sample2 установка свойства Twain32.DisableAfterAcquire=false никакого эффекта не произведет, т.к. там используется альтернативный интерфейс. Я проверил на Saraff.Twain.Sample1. В общем, все работало за исключением того, что интерфейс источника данных не закрывался (вообще). Эту проблему я исправил, код можно скачать из репозитория.
Nov 14, 2014 at 2:31 PM
Edited Nov 14, 2014 at 2:34 PM
Добрый вечер, SARAFF!
Попробовал сделать в Saraff.Twain.Sample1, предварительно изменил Twain32.cs в соответствии с вашими изменениями и скомпилил dll заново. Но проблема такая же, после сканирования первой страницы, при нажатии кнопки "Сканировать" в интерфейсе сканера появляется прогресс-бар и дальше ничего не происходит, и сам интерфейс не закрывается. Проверил на двух разных сканерах. Я использую 32 битную версию, но система 64 битная, может проблема в том что Saraff.Twain компилируется в 64 битный dll.
Coordinator
Nov 14, 2014 at 4:44 PM
Добрый день, AlexS33!
Да, проблема была. Исправил, код можно скачать из репозитория.
Nov 17, 2014 at 7:31 AM
Доброе утро!
Огромное спасибо, всё работает отлично!
Nov 17, 2014 at 12:32 PM
Всё таки не совсем хорошо работает, извините за частые вопросы. Сейчас при сканировании второй страницы (из интерфейса драйвера сканера), первая перезатирается в массиве _images, там всегда одно изображение. Подскажите, пожалуйста, в чём может быть причина.
Coordinator
Nov 17, 2014 at 1:28 PM
Edited Nov 17, 2014 at 1:31 PM
Добрый день, AlexS33!
Всё верно, так и должно быть. Массив изображений содержит изображения от одной операции сканирования (в native-ном режиме. в другиз режимах он вообще не используется). Т.е. пользователь нажал кнопку "сканировать" и с помощью автоподатчика отсканировал 10 страниц, соответственно 10 изображений будет и в массиве, а потом он еще раз нажал кнопку "сканировать" и с помощью автоподатчика отсканировал уже 50 страниц, соответственно 50 изображений будет и в массиве. А уже прикладная программа должна извлекать изображения из массиваи обрабатывать их (например, складывать их в общий массив изображений). Более того, вместо использования массива изображений (т.е. вместо обработки события Twain32.AcquireCompleted или совместно с ним) Вы можете обрабатывать событие Twain32.EndXfer для получения каждого изображения отдельно (т.е. по одному).

PS. Если Вам действительно очень понравилась библиотека Saraff.Twain.NET, то не поленитесь оставить развёрнутый отзыв о ней (необязательно на английском языке).
Nov 17, 2014 at 3:43 PM
Большое спасибо за развёрнутый ответ! Ещё такой вопрос, я сделал свой массив в _NativeTransferPictures():
                        this._images.Add(_img);
                        this._mas.Add(_img);
и очищаю его уже в своей прикладной программе this._twain.Clear(); функцией Twain32:
        public void Clear() {
            this._imgmas.Clear();
        }
Делаю это после сохранения массива mas в файл. Но когда нажимаю кнопку сканировать второй раз и вызывается метод Add, то предыдущее параметры значения в массиве _mas (т.е. _mas[0]) становится вида:
+       Height  "((new System.Collections.Generic.Mscorlib_CollectionDebugView<System.Drawing.Image>(this._twain._imgmas)).Items[0]).Height" запустило исключение типа "System.ArgumentException"   int {System.ArgumentException}
и таким образом перезатирается каждое предыдущее при повторном нажатии кнопки сканировать. Почему так происходит?
Coordinator
Nov 17, 2014 at 3:57 PM
Это говорит о том, что логика приложения нарушена: Вы перелажили функции прикладной программы (top level) на компонент (middle level). Я Вам предлагаю в Вашей программе создать массив изображений и копировать в него данные (тем более, что фактически копируется только ссылка):
private Collection<Image> _images=new Collection<Image>();

private void _twain32_AcquireCompleted(object sender, EventArgs e) {
    try {
        // ...
        for(int i=0; i<this._twain32.ImageCount; i++) {
            this._images.Add(this._twain32.GetImage(i));
        }
        // ...
    } catch(Exception ex) {
        // ...
    }
}
или
private Collection<Image> _images=new Collection<Image>();

private void _twain32_EndXfer(object sender, Twain32.EndXferEventArgs e) {
    try {
        // ...
        this._images.Add(e.Image);
        // ...
    } catch(Exception ex) {
        // ...
    }
}

а если надо очистить, то:
this._images.Clear();
Nov 18, 2014 at 9:15 AM
Огромное спасибо за помощь!!!