Powerbuilder中Kodak图像扫描控件应用技巧

Powerbuilder中Kodak图像扫描控件应用技巧
作者:佚名  

减小字体 增大字体

     摘  要 Powerbuilder中对Kodak图像扫描控件应用的技巧,主要是对扫描出来的图像进行文件头修改,以保证在Powerbuilder中的正确显示和应用。
     关键词 Powerbuilder;Kodak图像扫描控件;BMP;图像文件头
 

1  引言

    当前在开发管理信息系统中,Sybase公司的Powerbuilder(下文中简称PB)是一个使用非常广泛的语言工具,其数据窗口功能使得数据库系统的开发变得非常简单和快捷。笔者在使用Powerbuilder 10.5版本开发一个管理信息系统时,要求把人员的身份证照片扫描并存入数据库,在使用Kodak图像扫描控件时碰到了麻烦,图像能够扫描并存成图像文件,但是在PB中就是不能显示。经过笔者查阅各种资料,并对扫描形成的文件格式进行分析,终于解决了这个问题,笔者把相关技术知识及处理方法写出来,以便大家参考。

2 BMP文件的结构

    首先介绍一下BMP文件的知识:
    BMP文件可分为四个部分:位图文件头、位图信息头、彩色板、图像数据阵列。如:
    42 4D 50 07 00 00 00 00 00 00 3E 02 00 00 28 00
    00 00 24 00 00 00 24 00 00 00 01 00 08 00 00 00
    00 00 10 05 00 00 12 0B 00 00 12 0B 00 00 82 00
    00 00 82 00 00 00 FF FF FF 00 F3 F3 F3 00 E3 F4...

2.1 图像文件头

    (1)1:(这里的数字代表的是"字",即两个字节,下同)图像文件头。424Dh=’BM’,表示是Windows支持的BMP格式。
    (2)2-3:整个文件大小。5007 0000,为00000750h=1872。
    (3)4-5:保留,必须设置为0。
    (4)6-7:从文件开始到位图数据之间的偏移量。3E02 0000,为0000023Eh=574。
    (5)8-9:位图图信息头长度,一般为28h=40字节。
    (6)10-11:位图宽度,以像素为单位。2400 0000,为00000024h=36。
    (7)12-13:位图高度,以像素为单位。2400 0000,为00000024h=36。
    (8)14:位图的位面数,该值总是1。0100,为0001h=1。

2.2 位图信息头

    (1)15:每个像素的位数。有1(单色),4(16色),8(256色),16(64K色,高彩色),24(16M色,真彩色),32(4096M色,增强型真彩色)。0800为0008h=8。
    (2)16-17:压缩说明:有0(不压缩),1(RLE 8,8位RLE压缩),2(RLE 4,4位RLE压缩),3(Bitfields,位域存放)。RLE简单地说是采用像素数+像素值的方式进行压缩。T408采用的是位域存放方式,用两个字节表示一个像素,位域分配为r5b6g5。图中0000 0000为00000000h=0。
    (3)18-19:用字节数表示的位图数据的大小,该数必须是4的倍数,数值上等于位图宽度×位图高度×每个像素位数。1005 0000为00000510h=36×36×1h=1296。
    (4)20-21:用像素/米表示的水平分辨率。120B 0000为0000 0B12h=2834。
    (5)22-23:用像素/米表示的垂直分辨率。120B 0000为0000 0B12h=2834。
    (6)24-25:位图使用的颜色索引数。设为0的话,则说明使用所有调色板项。
    (7)26-27:对图象显示有重要影响的颜色索引的数目。如果是0,表示都重要。

2.3 彩色板

    28-35:彩色板规范。

2.4 图像数据阵列

    36-...:每两个字节表示一个像素。阵列中的第一个字节表示位图左下角的像素,而最后一个字节表示位图右上角的像素。 

3 用Kodak图像扫描控件扫描出来的BMP不能显示的原因分析

    通过BMP结构知识的了解,我们对BMP的结构有了一个基本的认识,对于PB中Kodak图像扫描控件扫描出来的BMP文件为什么不能显示,我们来看看扫描出来的文件头部分:
    42 4D AA A7 23 00 00 00 00 00 8A 00 00 00 7C 00
    00 00 28 04 00 00 DC 02 00 00 01 00 18 00 00 00
    00 00 20 A7 23 00 B4 2D 00 00 B4 2D 00 00 00 00
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    00 00 00 00 00 00 42 47 52 73 00 00 00 00 00 00
    对比BMP文件结构知识里面的说明,我们可以发现第8-9字节的内容为7C 00 00 00,而不是一般的28 00 00 00,查阅其它资料后发现:在Windows95、98、2000等操作系统中,位图信息头的长度并不一定是28h,因为微软已经制定出了新的BMP文件格式,其中的信息头结构变化比较大,长度加长。会不会是这个原因引起PB程序不能显示这个格式的Bmp文件呢?笔者把扫描的文件用UltraEdit进行了编辑,保持其它的不动,把8-9字节从7C 00 00 00改为28 00 00 00,然后用PB打开,果然,图像显示出来了。这证明PB只是认识以前格式的BMP文件,对新的BMP文件格式不能识别,因而不能显示。

4  解决方法及实例

    基于上述原因,我们可以在PB中把图像的文件头修改为PB认识的格式从而让PB能够处理从Kodak图像扫描控件扫描出来的图像文件。具体例程如下:
long  ll_i,ll_rt  
string  ls_imgpath  
ls_imgpath   =   GetCurrentDirectory( )+ "/sfz"//扫描图像存放路径  
ole_1.object.scroll=true//是否选中滚动  
ole_1.object.showsetupbeforescan=true//是否在扫描前显示扫描以设置界面  
ll_i=ole_1.object.openscanner()//打开扫描仪,成功返回0  
IF  ll_i=0  THEN  
  ole_1.object.filetype=3 //扫描图像的类型:   tif,bmp,jpg.....  
  ole_1.object.image=ls_imgpath//扫描图像存放路径  
  ole_1.object.MultiPage=false//是否多页  
  ole_1.object.pageoption=6//页选项,6就是改写所有页面(改写文件)  
  ole_1.object.scanto=2//扫描到,4就是只使用文件模版  
  ole_1.object.startscan()//开始扫描   
  ole_1.object.closescanner()//关闭扫描仪  
  integer fh,ret,loops,i
  blob b,b1
  string txtname,named
  txtname= ls_imgpath+'.bmp'
  long flen
  flen=filelength(txtname)
  fh = FileOpen(txtname,StreamMode!)
  IF flen > 32765 THEN
         IF Mod(flen,32765) = 0 THEN
              loops = flen/32765
         ELSE
              loops = (flen/32765) + 1
         END IF
  ELSE
         loops = 1
  END IF
  IF fh <> -1 THEN
         emp_pic=b
         for i=1 to loops
              FileRead(fh,b)
              Emp_pic=Emp_pic+b
         next
              FileClose(fh)
              b=emp_pic
              b=emp_pic
              b1=blobmid(b,1,14)+blob(char(40))+blobmid (b,17)
              Emp_pic=b1
              p_1.SetPicture(Emp_pic)
  END IF
  ELSE  
  messagebox("错误!","扫描仪打开错误,请检查扫描仪!")
  END IF

你可能感兴趣的:(pb)