作者:刘肖健 浙江工业大学工业设计研究院
Public bmpBlue() As Byte
Public bmpGreen() As Byte
Public bmpRed() As Byte
Public biWidth As Long '图像宽度
Public biHeight As Long '图像高度
Public biBitCount As Integer
Public Function OpenBitmap(filepath As String)
'打开文件
Open filepath For Binary As #1
'读BMP信息
Get #1, 19, biWidth '获取图像宽度
Get #1, 23, biHeight '获取图像高度
Get #1, 29, biBitCount '获取位数
'只能读24位BMP,不是则退出
If biBitCount <> 24 Then
MsgBox"Not 24-bit BMP."
Close #1
Exit Function
End If
'重定义记录RGB值的二维数组
ReDim bmpBlue(biHeight - 1, biWidth - 1) As Byte
ReDim bmpGreen(biHeight - 1, biWidth - 1) As Byte
ReDim bmpRed(biHeight - 1, biWidth - 1) As Byte
'RGB数组赋值
Dim n As Long
n = 0
Dim i As Integer, j As Integer
For i = 0 To biHeight - 1
For j = 0 TobiWidth - 1
DoEvents '控制权交给系统(防死机)
Get #1, 55+ n, bmpBlue(i, j)
n = n + 1
Get #1, 55+ n, bmpGreen(i, j)
n = n + 1
Get #1, 55+ n, bmpRed(i, j)
n = n + 1
Next
'补行尾空位(图形文档每行的存储空间字节数为4的整数倍,不足则补空位,因此每行首字节位置都是从4的整数倍开始)
n = n +biWidth Mod 4
Next
Close #1 '关闭文档
End Function
上述代码包含一个名为OpenBitmap的函数,其功能是打开一个指定位置的bmp图像文档(在参数filepath中指定),读出其全部像素的RGB值,保存在三个二维数组bmpRed、bmpGreen、bmpBlue中——它们分别用来保存RGB三个色彩分量。简单说,就是OpenBitmap函数执行完以后,三个数组内就写进了RGB值,可以用了。
模块定义了6个Public型的变量,它们在别的模块(如对话框)中也可以使用。
打开文档,从指定位置读出了图像的宽度(biWidth)和高度(biHeight)信息后,就可以定义(ReDim)三个二维数组的确切长度了。二维数组的第一个参数表示行,第二个参数表示列,如bmpRed(10,20)中的值代表图像第10行第20列的红色分量,一个0~255之间的整数。
bmp文档从第55个字节开始存放像素色彩信息,前面的都是文件头,存储像素行列数、文件大小、色彩位数等信息。RGB三个色值每个占一字节,依次存放,不过顺序是先Blue再Green再Red,所以读出的时候也要注意顺序不要弄错。
读像素语句Get #1,55 + n, bmpBlue(i, j)表示把#1号文件的第55+n个字节的数据写入bmpBlue(i, j)。完了以后,n的值加上1,作为下个数据的位置。
计数器n定义为Long型而不是Integer型,是因为通常图像的像素数十分巨大,Integer型整数占两个存储字节,能表达的最大整数是32767,只够表达一个200×163尺寸的一个bmp图像。Long型整数占4个字节,能表达的最大整数是2147483647,能表达50000×42949那么大的bmp图像,对一般图片足够用了。
读像素的双循环中有个DoEvents语句,用于向Windows系统移交控制权。这是因为读像素的工作量很大很耗时,容易造成“假死机”现象,移交控制权后,系统还可以响应其他程序,不会将该程序判定为死机。
循环里的最后一句n= n+biWidthMod 4,作用是跳过行末尾的空位。bmp图像的存储规则是,留给每行像素的存储空间是4的整数倍。如果实际的存储空间不是4的整数倍,比如每行27个像素,则用掉存储空间27×3=81字节,而实际分配的空间是84(4的整数倍)个字节,所以下一行第一个像素是从第85个字节开始存储。因此一行像素读完后要判断一下行末是否有空位,有的话就跳过去。Mod是一个运算符,作用是“整除后取余数”,如81 Mod 4的运算结果是1。每一行补上biWidth Mod 4个字节后刚好是4的倍数(biWidth是每行像素数)。
Public bmpBlue() As Byte
Public bmpGreen() As Byte
Public bmpRed() As Byte
Public biWidth As Long '图像宽度
Public biHeight As Long '图像高度
Public biBitCount As Integer
Public Function OpenBitmap(filepath As String)
'打开文件
Open filepath For Binary As #1
'读BMP信息
Get #1, 19, biWidth '获取图像宽度
Get #1, 23, biHeight '获取图像高度
Get #1, 29, biBitCount '获取位数
'只能读24位BMP,不是则退出
If biBitCount <> 24 Then
MsgBox"Not 24-bit BMP."
Close #1
Exit Function
End If
'重定义记录RGB值的二维数组
ReDim bmpBlue(biHeight - 1, biWidth - 1) As Byte
ReDim bmpGreen(biHeight - 1, biWidth - 1) As Byte
ReDim bmpRed(biHeight - 1, biWidth - 1) As Byte
'RGB数组赋值
Dim n As Long
n = 0
Dim i As Integer, j As Integer
For i = 0 To biHeight - 1
For j = 0 TobiWidth - 1
DoEvents '控制权交给系统(防死机)
Get #1, 55+ n, bmpBlue(i, j)
n = n + 1
Get #1, 55+ n, bmpGreen(i, j)
n = n + 1
Get #1, 55+ n, bmpRed(i, j)
n = n + 1
Next
'补行尾空位(图形文档每行的存储空间字节数为4的整数倍,不足则补空位,因此每行首字节位置都是从4的整数倍开始)
n = n +biWidth Mod 4
Next
Close #1 '关闭文档
End Function
上述代码包含一个名为OpenBitmap的函数,其功能是打开一个指定位置的bmp图像文档(在参数filepath中指定),读出其全部像素的RGB值,保存在三个二维数组bmpRed、bmpGreen、bmpBlue中——它们分别用来保存RGB三个色彩分量。简单说,就是OpenBitmap函数执行完以后,三个数组内就写进了RGB值,可以用了。
模块定义了6个Public型的变量,它们在别的模块(如对话框)中也可以使用。
打开文档,从指定位置读出了图像的宽度(biWidth)和高度(biHeight)信息后,就可以定义(ReDim)三个二维数组的确切长度了。二维数组的第一个参数表示行,第二个参数表示列,如bmpRed(10,20)中的值代表图像第10行第20列的红色分量,一个0~255之间的整数。
bmp文档从第55个字节开始存放像素色彩信息,前面的都是文件头,存储像素行列数、文件大小、色彩位数等信息。RGB三个色值每个占一字节,依次存放,不过顺序是先Blue再Green再Red,所以读出的时候也要注意顺序不要弄错。
读像素语句Get #1,55 + n, bmpBlue(i, j)表示把#1号文件的第55+n个字节的数据写入bmpBlue(i, j)。完了以后,n的值加上1,作为下个数据的位置。
计数器n定义为Long型而不是Integer型,是因为通常图像的像素数十分巨大,Integer型整数占两个存储字节,能表达的最大整数是32767,只够表达一个200×163尺寸的一个bmp图像。Long型整数占4个字节,能表达的最大整数是2147483647,能表达50000×42949那么大的bmp图像,对一般图片足够用了。
读像素的双循环中有个DoEvents语句,用于向Windows系统移交控制权。这是因为读像素的工作量很大很耗时,容易造成“假死机”现象,移交控制权后,系统还可以响应其他程序,不会将该程序判定为死机。
循环里的最后一句n= n+biWidthMod 4,作用是跳过行末尾的空位。bmp图像的存储规则是,留给每行像素的存储空间是4的整数倍。如果实际的存储空间不是4的整数倍,比如每行27个像素,则用掉存储空间27×3=81字节,而实际分配的空间是84(4的整数倍)个字节,所以下一行第一个像素是从第85个字节开始存储。因此一行像素读完后要判断一下行末是否有空位,有的话就跳过去。Mod是一个运算符,作用是“整除后取余数”,如81 Mod 4的运算结果是1。每一行补上biWidth Mod 4个字节后刚好是4的倍数(biWidth是每行像素数)。









