Если вы в плотную занимаетесь обработкой графики при помощи Delphi и вам надоело каждый раз вводить изображение через другие программы, то эта короткая как раз для вас. Она расскажет вам, как с помощью этого языка программирования организовать ввод изображения прямо со сканера или другого TWAIN устройства.
Начало
Начнем мы как всегда с формы нашего тестового приложения. Но перед тем импортируем(рис.1) в наш проект библиотеку типов IMGSCAN.OCX(рис.2). Которая и будет заведовать сканированием. Возможно внимательный программист заметит, что кроме IMGSCAN.OCX в библиотеке типов присутствует еще одна, привязанная к конкретному сканеру(рис.3) и которая естественно позволяет более гибко его настроить. Но это чревато потерей универсальности нашего приложения и применимо, если только вы пишете для себя или для тех, у кого
установлен тот же драйвер сканера. Если это так, то настоятельно советую разобраться именно с библиотекой Вашего сканера, если же вы готовы пожертвовать функциональностью программы в пользу ее универсальности - читайте дальше.
После того как вы импортировали IMGSCAN.OCX. У вас должен появится новый модуль (ScanLibCtl_TLB.pas). Если вы нажали на кнопку Install вместо CreateUnit(рис.2), то у вас в закладке ActiveX должен появится новый компонент TImgScan и вы можете спокойно перекинуть его на форму. Я этого не делал и поэтому мне потребуется создать его явно в Runtime режиме.
Далее для проверки правильности наших действий мы перекинем на форму компонент TImage(рис.4) в котором будем отображать отсканированное изображение.
Сканирование
Для сканирование изображений в реакцию кнопки на нажатие напишем такой код:
procedure TForm1.Button1Click(Sender: TObject);
var Scan:TImgScan;
begin
Button1.Enabled:=False;
try
Scan:=TImgScan.Create(Self);
if Scan.ScannerAvailable then
begin
try
Scan.OpenScanner;
Scan.FileType:=BMP_Bitmap;
Scan.ScanTo:=DisplayAndFile;
Scan.Image:='Test.bmp';
Scan.StartScan;
Application.ProcessMessages;
finally
Scan.CloseScanner;
Image1.Stretch:=True;
Image1.Picture.LoadFromFile('Test.bmp');
end;
end else Button1.Caption:='NoScanner';
Scan.Free;
finally
Button1.Enabled:=True;
end;
end;
как видно из кода сначала мы создаем экземпляр класса TImgScan (те, кто создавал его в DesignTime режиме должны пропустить эту строчку кода и перейти сразу к блоку ). После этого мы проверяем свободен ли сканнер и если да, то задаем параметры сканирования (тип отсканированного изображения, имя файла, а так же тип отображения) и сканируем.
По завершении сканирования закрываем сканнер и отображаем результат(рис.5).
Дополнительные опции
Кроме использованных в коде программы опций в компонента TImgScan есть еще не мало полезный возможностей.
Так свойство FileType позволяет задать тип конечного файла: TIFF, BMP_Bitmap, AWD_MicrosoftFax, которые задают соответственно конечный файл в формате TIFF, BMP или в специальном Fax-формате. Свойство ScanTo определяет тип сканирования:
DisplayOnly - только отображение на экране
DisplayAndFile - отображение на экране и запись результата на диск
FileOnly - без отображения результата на экране
DisplayAndUseFileTemplate - Отображение на экране и сохранние на диск с использованием шаблона сохранения
UseFileTemplateOnly - только сохранение с использованием шаблона
FaxOnly - сканирование факса
И т.п. подробнее можно узнать из справки к даному компоненту
Вместо завершительного слова...
хотелось бы сказать, что сканирование изображений таким способом не является оптимальным. Есть более универсальные способы доставки изображений из сканера в вашу программу. Один из них - использовать ActiveX библиотеки производителя, но, как уже было замечено это не пройдет по причине потери универсальности. Можно также попытаться написать свою собственную библиотеку взаимодействия с драйвером сканера. Для этого надо разобраться с ".ds" файлами расположенными в TWAIN_32 каталоге директории Windows.
Листинг.1. Приведенный ниже листинг немного скорректирован с учетом того, что изображения должно отображаться пропорционально.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Image1: TImage;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
Uses ScanLibCtl_TLB;
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var Scan:TImgScan;
BMP:TBitmap;
R:Single;
begin
Button1.Enabled:=False;
try
Scan:=TImgScan.Create(Self);
if Scan.ScannerAvailable then
begin
try
Scan.OpenScanner;
Scan.FileType:=BMP_Bitmap;
Scan.ScanTo:=DisplayAndFile;
Scan.Image:='Test.bmp';
Scan.StartScan;
Application.ProcessMessages;
finally
Scan.CloseScanner;
BMP:=TBitmap.Create;
BMP.LoadFromFile('Test.bmp');
R:=BMP.Width/BMP.Height;
Image1.Height:=Round(Image1.Width/R);
Image1.Stretch:=True;
Image1.Picture.Assign(BMP);
end;
end else Button1.Caption:='NoScanner';
Scan.Free;
finally
Button1.Enabled:=True;
end;
end;
end.