Введение
В отличие от принтеров сканеры изначально не поддерживались ОС Windows и не
имеют API для работы с ними. В начале своего появления сканеры взаимодействовали
с программами посредством уникального для каждой модели сканера интерфейса, что
серьезно затрудняло включение поддержки работы со сканером в прикладные
программы.
Для решения этой проблемы был разработан TWAIN - индустриальный стандарт
интерфейса программного обеспечения для передачи изображений из различных
устройств в Windows и Macintosh. Стандарт издан и поддерживается TWAIN рабочей
группой - официальный сайт
www.twain.org.
Стандарт издан в 1992 г. В настоящее время действует версия 1.9 от января 2000
г. Абревеатура TWAIN изначально не имела какого-то определенного смысла хотя
позже была придумана расшифровка: (Technology Without An Interesting Name -
Технология без интересного имени). TWAIN - не протокол аппаратного уровня, он
требует драйвера (названного Data Source или DS) для каждого устройства .
К настоящему времени (май 2000 г.) TWAIN доступен для Windows 3.1 и выше
(Intel и совместимые процессоры), Macintosh и OS/2. Для Linux самый близкий
стандарт - SANE..
Менеджер TWAIN (DSM) - действует как координатор между приложениями и
Источником Данных (Data Source). DSM имеет минимальный пользовательский
интерфейс - только выбор DS. Все взаимодействие с пользователем вне прикладной
программы осуществляется по средствам DS.
Каждый источник данных разрабатывается непосредственно производителем
соответствующих устройств. И их поддержка стандарта TWAIN осуществляется на
добровольной основе.
Использование TWAIN
DSM и DS это DLLs загружаемые в адресное пространство приложения и работают
как подпрограммы приложения. DSM использует межпроцесcную связь, что бы
координировать действия со своими копиями, когда больше чем одна программа
использует TWAIN.
Упрощенная схема действия приложения использующего TWAIN:
- Открыть диалог настройки соответствующего устройства (диалог
отображает DS) и задать соответствующие настройки.
- Приложение ожидает сообщение от DS, что изображение готово.
Во время ожидания все зарегистрированные сообщения будут
направляться через TWAIN. Если это не будет выполняться, то
приложение не получит сообщения о готовности изображения.
- Приложение принимает изображение от DS.
TWAIN определяет три типа передачи изображения:
Native - в Windows это DIB в памяти
Memory - как блоки пикселей в буферах памяти
File - DS записывает изображение непосредственно в файл
(не обязательно поддерживается) - Приложение закрывает DS.
Использование EZTWAIN.
Данная библиотека была разработана, что бы упростить разработку программ
использующих TWAIN предоставляя разработчику упрощенную версию TWAIN API.
EZTWAN обеспечивает передачу всех windows сообщений через TWAIN и ожидает
сообщения о готовности изображения.
Библиотека EZTWAIN является свободно распространяемой библиотекой с открытыми
исходными кодами. В настоящее время выпущена версия 1.12. Библиотеку можно
свободно скачать с сайта:
www.dosadi.com,
библиотека написана на C и предназначена для использования как DLL, необходимый
для ее использования с Delphi модуль так же можно скачать с сайта. Кроме нее у
меня с сайта
можно скачать
модификацию данной библиотеки, предназначенную для статической компоновки с
программой на Delphi. Указанная версия (MultiTWAIN for Delphi) не требует
наличия библиотеки EZTW32.DLL.
Структура программы.
Используемые функции.
Перед вызовом функций сканирования необходимо вызвать функцию:
TWAIN_SelectImageSource(hwnd: HWND): Integer;.
Данная функция позволяет выбрать источник получения данных из списка TWAIN
совместимых устройств, в качестве параметра она получает хендл основного окна
прикладной программы. Следует заменить, что если в системе имеется одно TWAIN
совместимое устройство, то вызывать функцию не обязательно.
Для получения изображения служит функция:
TWAIN_AcquireNative(hwnd: HWND; pixmask: Integer): HBitmap;
где:
hwnd - хендел основного окна прикладной программы (допускается указывать 0);
pixmask - режим сканирования ( необходимо задавать 0 - указание другого режима
может приводить к ошибке) ;
hBitmap - указатель на область памяти, содержащей полученные данные в DIB
формате.
По окончании работы с DIB данными их необходимо удалить вызвав процедуру:
TWAIN_FreeNative(hDIB: HBitmap);
где:
hDIB - указатель, полученный при вызове функции TWAIN_AcquireNative.
Для облегчения обработки полученных DIB данных в библиотеке имеется несколько
сервисных функций:
TWAIN_DibWidth(hDib: HBitmap):
Integer; |
Получает ширину изображения в
пикселях |
TWAIN_DibHeight(hDib: HBitmap):
Integer; |
Получает высоту изображения в
пикселях |
TWAIN_CreateDibPalette(hdib:
HBitmap): Integer; |
Получает цветовую палитру
изображения |
TWAIN_DrawDibToDC(hDC: HDC;
dx, dy, w, h: Integer;
hDib: HBitmap;
sx, sy: Integer
); |
Передает DIB данные в формате
совместимым с указанным
контекстом устройства. |
Пример программы.
Полный текст примера можно взять
отсюда. Мы рассмотрим только функцию получения данных с TWAIN
устройства:
procedure TForm1.Accquire1Click(Sender: TObject);
var
dat: hBitMap;
PInfo: PBitMapInfoHeader;
Height,Width:integer;
{Функция возведения 2 в степень s}
function stp2(s:byte):longint;
var
m: longint;
i: byte;
begin
m:=2;
for i:=2 to s do m:=m*2;
stp2:=m;
end;
begin
{Получаем указатель на графические данные}
dat:=TWAIN_AcquireNative(Handle,0);
if dat <> 0 then begin
{Получаем указатель на область памяти содержащей DIB
данные и блокируем область памяти}
PInfo:=GlobalLock(dat);
{Анализируем полученные данные}
Height:=PInfo.biHeight ;
Width:=PInfo.biWidth ;
{Узнаем размер полученного изображения в сантиметрах}
Wcm.Caption :=floatToStrF(100/PInfo.biXPelsPerMeter*Width,ffNumber,8,3)
+' cm';
Hcm.Caption :=floatToStrF(100/PInfo.biYPelsPerMeter*Height,ffNumber,8,3)
+' cm';
{Определяем число цветов в изображении}
Colors.Caption := floatToStrF(stp2(PInfo.biBitCount),ffNumber,8,0)+
' цветов';
{Разблокируем память}
GlobalUnlock(dat);
{Передаем в битовую матрицу графические данные}
{И устанавливаем перехват ошибок}
try
MyBitMap.Palette :=TWAIN_CreateDibPalette(dat);
MyBitMap.Width := Width;
MyBitMap.Height := Height;
TWAIN_DrawDibToDC(MyBitMap.Canvas.Handle,0,0,Width,Height,dat,0,0);
except
{Обрабатываем наиболее вероятную ошибку связанную с не хваткой ресурсов
для загрузки изображения}
on EOutOFResources do
MessageDlg('TBitMap: Нет ресурсов для загрузки
изображения!',
mtError,[mbOk],0);
end;
{Отображаем графические данные}
Image1.Picture.Graphic:=MyBitMap;
{Освобождаем память занятую графическими данными}
TWAIN_FreeNative(dat);
end;
end;
Обработка ошибок необходима, так как объект TBitMap имеет серьезные
ограничения на размер создаваемого изображения. При этом производится обработка
наиболее вероятной ошибки, в случае возникновения другой ошибки, ее обработка
будет передана обработчику по умолчанию. Обработка ошибки в данном случае
заключается в выдаче диагностического сообщения, в прикладной программе можно
реализовать выполнение любых необходимых действий, например, произвести
уменьшение разрешения и повторно подать на загрузку в TBitMap.
Заключение.
Приведенный здесь пример тестировался на сканере Umax 2000P с драйвером
VistaScan32 V3.52. При получении изображений следует помнить, что максимальный
размер блока памяти, который может распределить Windows, составляет 2 Гб и при
попытке сканировании страниц формата А4 с высоким разрешением можно превысить
этот предел. Кроме того, достаточно простой в обращении объект TBitMap имеет
куда более серьезные ограничения на размер загружаемых изображений, что требует
непосредственной работы с DIB данными. Но это уже тема для отдельной статьи.
Если у Вас появились вопросы или предложения пишите мне:
speclab@4unet.ru
|