---- 在利用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) and (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. |