[DELPHI]在Delphi中控制掃描儀
---- 在利用Delphi開發資訊管理系統時,常常要處理圖象,這也是資訊管理系統發展的必然趨勢。如何在Delphi中透過掃描器獲得所需的圖象資訊呢?不外乎有三種基本的方法:
透過圖象處理軟體,比如說photoshop等,透過它們的掃描圖象的功能,加工成一定格式的圖象後再在自己的系統中利用;
透過掃描器介面Twain.DLL 。該介面是在安裝掃描器時提供的,它實際上是一個Plugin插件,它透過一系列函數來控制掃描器;
透過構件技術來控制掃描器。
---- 利用第一種方法能減少程式設計的複雜度,但是系統的整合度不高,使用者使用上也不方便;第二種方法能在驅動程式層級直接控制掃描儀,能
在程式上提供最大的靈活性和可控制性;第三種方法能充分利用Delphi的可視化構件技術,安全、靈活、自由地利用掃描器。其實第三種方法也
是建立在掃描器介面Twain.DLL之上的。本文論述的方法就採用第三種。
---- Windows9X在其附件中提供了「映像」可選件,該附件是採用OCX構件來控制掃描器的,共有imgEdit、imgAnntool、imgScan、imgAdmin 四個,有這四個構件基本上就能完全控制掃描器。在Delphi中的用法如下: 在Windows9x中選擇安裝「映像」。 (在控制台中選擇“新增/刪除程式”,再選擇“安裝Windows”,點擊“附件”複選框,然後從“詳細資料”按鈕中可以找到“映像”)
啟動Delphi,選擇“Component”選單項目下的“Import ActiveX Control”,
這時可以看到清單中有「Wang 圖象編輯控制、Wang 圖象掃描控制、Wang
圖像管理控制、Wang 圖象縮圖控制”,選取這四項,然後點選“Install”
按鈕,這時在構件面板上的ActiveX舌標下就可以看到這四個構件的圖示。
---- ImgScan 的主要屬性:FileType:圖象的檔案類型(此構件支援三
種:TIFF,BMP,AWD);
ScanTo:返回或設定被掃描圖象的目的;
可取值含義
0 (缺省) 顯示被掃描的圖象.
1 顯示被掃描的圖象並寫入一個檔案.
2 把圖象寫入一個文件
3 以模板方式把圖象寫入文件並顯示.
4 . 以模板方式把圖象寫入文件
5 傳真被掃描的圖象
注意:如果取缺省值0,
必須和Wang ImgEdit 構件搭配使用。
DestImageControl:Wang ImgEdit構件名;
Zoom:圖象的放縮比例
ImgScan 的主要方法:OpenScanner :開啟掃描器;
CloseScanner :關閉掃描器;
StartScan : 開始掃描;
StopScan : 停止掃描
---- ImgEdit 的屬性主要是控制掃描圖象的解析度、圖象的寬高、是否
允許對圖象進行局部選擇等;其方法主要有拷貝、剪切圖像到貼板,
從貼上複製圖象,旋轉、放縮、 鏡象圖象;列印、儲存、刷新圖像等。
---- 關於上述四個OCX構件的詳細使用說明可在Delphi中查看其自帶的
幫助系統。
---- 以下是使用這兩個構件的一些範例:
PRocedure Tscanf.N1Click(Sender: TObject);
begin
ImgScan1.ShowSelectScanner;
file://選擇系統中已安裝的掃描儀
end;
procedure Tscanf.N2Click(Sender: TObject);
begin
imgedit1.zoom:=100; file://設定圖象的放縮因子
if not imgscan1.ScannerAvailable then
file://如果選擇的掃描器不可用
imgscan1.OpenScanner;//開啟掃描儀
imgscan1.StartScan; file://開始掃描圖象
imgscan1.CloseScanner; file://關閉掃描儀
end;
procedure Tscanf.N8Click(Sender: TObject);
begin
if (imgedit1.IsClipboardDataAvailable
and imgedit1.ImageDisplayed ) then
imgedit1.ClipboardPaste(selleft,seltop);
file://從剪貼簿貼上圖象,其參數為Imgedit的顯示區域的起始座標
end;
procedure Tscanf.N1801Click(Sender: TObject);
begin
if imgedit1.ImageDisplayed then
imgedit1.Flip; file://鏡像圖象
end;
procedure Tscanf.N901Click(Sender: TObject);
begin
if imgedit1.ImageDisplayed then
imgedit1.RotateRight file://向右旋轉圖象
end;
procedure Tscanf.N6Click(Sender: TObject);
begin
imgedit1.DrawSelectionRect(selleft,
seltop,selwidth,selheight);//進行圖象局部選擇
imgedit1.ClipboardCut(selleft,seltop,
selwidth,selheight);//剪下所選區域
end;
---- 注意:在DELPHI中使用Imgedit構件的拷貝和剪下功能時,會出現
以下問題:
---- 1、 如果把整幅圖像都選中,沒有任何問題;
---- 2、 如果選擇了局部區域,則拷貝和剪切的區域會發生漂移;
---- 3、 如果DELPHI做的是MS SQL後端資料庫的客戶端介面,那麼在把
圖象內容寫入資料庫的圖象欄位時,BDE(資料庫引擎)會報錯。這是
DELPHI3。0和4。0的BUG,4。0的升級套件可以解決這個問題。
---- 至於第二個問題,可這樣解決:在Imgedit的onSelectionRectDrawn
事件中寫一段程式碼,把選擇區域的邊界值存到四個全域變數中,在拷貝
和剪切之前用先前保存的變數再進行一次選擇即可(當然,這一切都在後
台進行的,見前面的例子)。
---- 開發環境:DELPHI4。0,HP ScanJet 4P掃描器;
---- 附原始碼。
unit scanu;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls,
Forms, Dialogs, Menus, ScanLib_TLB, ExtCtrls, AxCtrls,
OleCtrls, ImgeditLib_TLB;
type
Tscanf = class(TForm)
MainMenu1: TMainMenu;
F1: TMenuItem;
N15: TMenuItem;
N1: TMenuItem;
N2: TMenuItem;
N16: TMenuItem;
N11: TMenuItem;
N5: TMenuItem;
C1: TMenuItem;
N4: TMenuItem;
E1: TMenuItem;
N6: TMenuItem;
N7: TMenuItem;
N8: TMenuItem;
N3: TMenuItem;
N10: TMenuItem;
N9: TMenuItem;
N1801: TMenuItem;
N901: TMenuItem;
N902: TMenuItem;
H1: TMenuItem;
N12: TMenuItem;
N13: TMenuItem;
ImgEdit1: TImgEdit;
Bevel1: TBevel;
ImgScan1: TImgScan;
Bevel2: TBevel;
procedure N4Click(Sender: TObject);
procedure N1Click(Sender: TObject);
procedure N2Click(Sender: TObject);
procedure C1Click(Sender: TObject);
procedure N8Click(Sender: TObject);
procedure N1801Click(Sender: TObject);
procedure N901Click(Sender: TObject);
procedure N902Click(Sender: TObject);
procedure N6Click(Sender: TObject);
procedure N7Click(Sender: TObject);
procedure ImgEdit1SelectionRectDrawn(Sender: TObject; Left,Top,
Width, Height: Integer);
procedure N11Click(Sender: TObject);
private
{ Private declarations }
public
selleft,seltop,selwidth,selheight:integer;
{ Public declarations }
end;
var
scanf: Tscanf;
implementation
{$R *.DFM}
procedure Tscanf.N4Click(Sender: TObject);
begin
imgedit1.ClearDisplay;
close;
end;
procedure Tscanf.N1Click(Sender: TObject);
begin
ImgScan1.ShowSelectScanner;
end;
procedure Tscanf.N2Click(Sender: TObject);
begin
imgedit1.zoom:=100;
if not imgscan1.ScannerAvailable then
imgscan1.OpenScanner;
imgscan1.StartScan;
imgscan1.CloseScanner;
end;
procedure Tscanf.C1Click(Sender: TObject);
begin
if imgedit1.ImageDisplayed then
begin
imgedit1.ClearDisplay;
imgedit1.zoom:=100;
end;
end;
procedure Tscanf.N8Click(Sender: TObject);
begin
if (imgedit1.IsClipboardDataAvailable and imgedit1.ImageDisplayed )
then
imgedit1.ClipboardPaste(selleft,seltop);
end;
procedure Tscanf.N1801Click(Sender: TObject);
begin
if imgedit1.ImageDisplayed then
imgedit1.Flip;
end;
procedure Tscanf.N901Click(Sender: TObject);
begin
if imgedit1.ImageDisplayed then
imgedit1.RotateRight
end;
procedure Tscanf.N902Click(Sender: TObject);
begin
if imgedit1.ImageDisplayed then
imgedit1.RotateLeft;
end;
procedure Tscanf.N6Click(Sender: TObject);
begin
imgedit1.DrawSelectionRect(selleft,seltop,selwidth,selheight);
imgedit1.ClipboardCut(selleft,seltop,selwidth,selheight);
end;
procedure Tscanf.N7Click(Sender: TObject);
begin
imgedit1.DrawSelectionRect(selleft,seltop,selwidth,selheight);
imgedit1.ClipboardCopy(selleft,seltop,selwidth,selheight);
end;
procedure Tscanf.ImgEdit1SelectionRectDrawn(Sender: TObject; Left,
Top, Width, Height: Integer);
begin
if ((width=0) 和 (height=0))then
begin
n3.Enabled:=false;
n6.Enabled:=false;
n7.Enabled:=false;
selleft:=left;
seltop:=top;
selwidth:=width;
selheight:=height;
end
else begin
n6.Enabled:=true;
n7.Enabled:=true;
selleft:=left;
seltop:=top;
selwidth:=width;
selheight:=height;
end;
end;
procedure Tscanf.N11Click(Sender: TObject);
begin
if not imgedit1.IsClipboardDataAvailable then
if imgedit1.imagedisplayed then
imgedit1.ClipboardCopy(0,0,imgedit1.Width,imgedit1.Height);
end;
end