https://blog.csdn.net/supernpc/article/details/4351645
原标题:Powerbuilder中Kodak图像扫描控件应用技巧
***这只是特例,例如一些dll生成的二维码bmp也无法显示。所以对于低版本的pb只能采用其他的控件比如柯达控件来显示。
因为这个问题不仅在bmp格式,而且jpg也存在。
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 |