VB图象处理功能小考
最近,因帮别人做VB的图象处理程序,查阅了一些资料,也做了一些实验,有些问题,也有些看法,写下来作为备忘。
VB最基本的图象控件是:PictureBox和Image,后者主要用来显示图片,前者既可以显示图片,也可以用来对所显示图片进行必要的处理,例如,对图片进行旋转、放大、缩小,乃至通过对像素的处理达到对图象的所需的加工处理。从现有资料看,VB针对PictureBox提供的处理函数主要有:Point|Pset; GetPixel|SetPixel;众所周知,这两组函数虽然方便使用,但速度慢。在我的实验中,还发现这两组函数存在一个根本性的区别,用Pset函数在一个Picture属性为None的PictureBox控件中显示出来的图象,可以通过savePicture Picture1.Image “FileName”存储所显示的图象(bmp)。但是,用SetPixel函数在一个Picture属性为None的PictureBox控件中显示出来的图象,不可以通过savePicture Picture1.Image “FileName”存储所显示的图象(存储结果是控件的背景—灰色矩形)。究其原因,我认为是:Pset函数是向PictureBox控件上显示图象、而SetPixe函数是向PictureBox的设备(即矩形范围)内显示图象,前者显示出来的图象属于PictureBox从而其Image属性也具有该图象,但SetPixe函数是根据hDC获得矩形区域进行作图,所作图象并不属于PictureBox控件。这可以从它们的参数的不同来区别。不妨做一个试验,对这两个函数显示的图象,在显示完成之后用方法Picture1.refresh进行刷新,Pset所显示的图象仍然显示、而SetPixe显示的图象却不再存在。这里,还要说一下PictureBox控件的属性Picture和Image,前者是可读可写的、而后者是只读的,那么,Image属性的值是从那得到的呢?首先,当Picture属性Load了图象并在控件上显示后,Image属性的值就是该图象;此外,当通过Pset函数在控件上显示了图象,控件的Image属性也获得了该图象。这就是为什么不能用操作SavePicture Picture1.picture来存储Pset所显示的图象,因为,此时控件的Picture属性仍然是None,即其指针为Null。
由于Point|Pset; GetPixel|SetPixel函数的速度太慢,许多同行寻求其他途径,例如调用GDI32的函数,但是,StretchBlt函数虽然速度快,但是,由于函数的实参仍然是hDC,所以,该函数也仅仅是复制设备场景(可伸缩),即用该函数在一个Picture属性为None的PictureBox控件上显示的图象,还是不能用SavePicture函数存储为BMP文件。在GDI32的函数中,GetDIBits|SetDIBits函数是不错的选择,可用GetDIBits先将图象数据读入缓冲区(自己定义的数组),经过加工处理后,再用SetDIBits函数将图象数据放入设备的图象中。这个网友已经给出了若干声明和相应的示例,为了完整,将其摘录如下:
Option Explicit
Private Type BITMAPFILEHEADER
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
Private Type Bitmap
bmType As Long
bmWidth As Long</