vb中有8位宽度的数组,已知宽高如何显示成灰度图呢?
vb中接受到数据采集卡的数据,8位宽度的,我把他存储到数组中,现在需要把数组中的数据显示成灰度图,灰度图的宽度和高度都已知,这要怎么做啊,最好能给个程序哦,我刚做VB不久还很多都没接触到哦!谢谢各位了!! --------------------编程问答-------------------- 这个得看你的数据是有符号的还是无符号的了. VB6的integer是有符号的, 超过32767就变成负数了 --------------------编程问答-------------------- 无符号的哦 --------------------编程问答-------------------- RGB色彩系统将所有的颜色值以24个二进制位来表示,也就是三个字节大小表示一个颜色值。而这三个字节是怎么排列来说明这种颜色呢?这个你应该知道了,第一个字节是红色值,第二个字节是绿色值,第三个字节为蓝色值,如红色这么表示:0xFF0000 绿色这么表示:0x00FF00 蓝色这么表示:0x0000FF那还有个问题,黑色与白色还有灰色怎么表示呢?看看下面的例子把:
0x000000 黑色
0xFFFFFF 白色
0x808080 灰色
在仔细看看
0x00 00 00 黑色
0xFF FF FF 白色
0x80 80 80 灰色
黑白灰的关系是他们的R、G、B 三个值都相等,而值越高越亮,值越低越暗,这么看来,灰度值的特性就是 R、G、B 相等,因为这个条件,也就限制了灰度色只有从 00-FF 范围的 256 个变化。
既然知道了灰度色的定义和范围,那该怎么将彩色图像转换为灰度图像呢?
其实很简单,也是从 R、G、B这几个色彩分量入手。
虽然彩色里 R、G、B 可能每个值都不同,但我们的目的是去这几个分量的平均值,就可以实现这样的灰度变化,公式很简单:gray = Int((R+G+B)/3)
只要把这个 gray 处理到新的 RGB 位置中就完成了这一个色彩的运算,如 NewColor = RGB(gray,gray,gray)
接下来再说说位图数据,位图数据其实就是有 R1,G1,B1,R2,G2,B2... 这样一个一个的色彩数据所构成的一张图像数据,当然,标准的位图结构还有一点小规范,如存储数据是重下至上从左到右的存储,每一行像素如果不是4的倍数就多加几个字节补齐为4的倍数,而这种规范还在GDI中被运用,而GDI中却不是4的倍数,而是2的倍数。这都是Windows中位图数据结构上的一些小规范,如果没看过这方面的资料,很容易搞出问题来。
接下来写一个简单的灰度运算范例给你看看:
Dim BmpWidth As Long
Dim BmpHeight As Long
Dim BmpColorBit As Long
Dim BmpWidthSize As Long
Dim BmpData() As Byte
Dim X As Long,Y As Long,ColorAddr As Long
Dim cRead As long,cGreen As Long,cBlue As Long,cGray As Long
' 比如直接读取一个文件中的位图数据
Redim BmpData(FileLen("C:\1.bdf")-1)
Open "C:\1.bdf" For Binary As #1
Get #1,1,BmpData
Close #1
' 因为事先已知这个数据文件是RGB色彩系统的BMP数据,并且已知宽高等相关信息
' 所以直接设置相关数据便可
BmpWidth = 333 ' 设置已知宽度值
BmpHeight = 80 ' 设置已知高度值
BmpColorBit = 24 ' 设置已知色彩比特位
' 运算相关参数
If BmpColorBit<8 Then
End ' 不支持小于8位的色彩系统(你也可以考虑去支持它,呵呵)
End If
BmpWidthSize = BmpWidth * (BmpColorBit/8)
If BmpWidthSize Mod 4 <> 0 Then
BmpWidthSize = BmpWidthSize + (4 - BmpWidthSize Mod 4)
End If
' 开始处理灰度色彩
For Y=0 To BmpHeight
For X=0 To BmpWidth
ColorAddr = (Y * BmpWidthSize) + (X * (BmpColorBit/8))
' 因为数据存储结构原因,RGB的位置会反过来
cBlue = BmpData(ColorAddr) ' 取得蓝色分量
cGreen = BmpData(ColorAddr+1) ' 取得绿色分量
cRead = BmpData(ColorAddr+2) ' 取得红色分量
cGray = int((cRead+cGreen+cBlue)/3)
' 将运算好的内容放回数组替换原来的值
BmpData(ColorAddr) = cGray
BmpData(ColorAddr+1) = cGray
BmpData(ColorAddr+2) = cGray
Next X
Next Y
' 完成灰度处理将数据保存到另外一个文件
Open "C:\2.bdf" For Binary As #1
Put #1,1,BmpData
Close #1
大致就是这种过程,你可以根据你自己的需求改一下,如果使用GDI,还可以直接用GetBitmapBits或SetBitmapBits这样的函数取出内存图像数据运算,然后将运算过的数据放回去显示。 --------------------编程问答-------------------- 楼上正解,很详细,我就不班门弄斧了 --------------------编程问答--------------------
抱歉,看错了,你的数据是8位的,那么就可以用byte类型了. 灰度图的话256阶正好.
最最简单的方法:
假设你收到的数据放在数组BT()里面
图像的宽度是W, 高度是H的话,程序如下:
sub DrawGray() '假设你之前的W,H,BT()都已经在外部定义为全局型,再假设你是画到控件Picture1里面
dim X as long
dim Y as long
dim C as long
picture1.visible=false
for Y =0 to H -1
For X =0 to W-1
C=BT(Y*W+X)
Picture1.Pset(X),(Y),RGB(C,C,C)
NEXT
NEXT
PICTURE1.VISIBLE=TRUE
差不多就是这个一个过程吧, 具体差异可能存在于: 你的数据排列方式可能是从上到下一行一行下来的, 甚至也可能是从左到右一列一列的, 要看你数据源的扫描方式了, 只需要更改一下BT(Y*W+X)的算法即可
--------------------编程问答-------------------- 上面忘记交代一句了, 请将picture控件的scalemode设为pixel, 可以去控件属性里面找 --------------------编程问答-------------------- 各位分析的很透彻,我已经使用一种方法显示在界面上了,但最近又不知道如何存储成图片,图片的格式无所谓了,我发我调好的程序贴出来,大家再帮帮忙看怎么才能在我这程序的基础上把图片存储下来呢?
'Private Const BI_RGB = 0&
'Private Const DIB_RGB_COLORS = 0
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
'rgbReserved As Byte
End Type
Private Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
Private Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal wSrcWidth As Long, ByVal wSrcHeight As Long, lpBits As Any, lpBitsInfo As BITMAPINFO, ByVal wUsage As Long, ByVal dwRop As Long) As Long
Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Dim ImageData(120 * 72&) As RGBQUAD '模拟图像数据
Private Sub Command1_Click()
Dim Index As Long
For Index = 0 To 120 * 72&
'ImageData(Index).rgbRed = Rnd * 255 '这里是模拟图像数据,我假定图像高度是300像素
ImageData(Index).rgbGreen = Rnd * 255 '这里是模拟图像数据,我假定图像高度是300像素
'ImageData(Index).rgbBlue = Rnd * 255 '这里是模拟图像数据,我假定图像高度是300像素
Next
Dim Gray As Byte
'处理灰度图(区Green法)
For Index = 0 To 120 * 72&
Gray = ImageData(Index).rgbGreen
ImageData(Index).rgbRed = Gray
ImageData(Index).rgbBlue = Gray
Next
ShowBitmap Me.hdc, 645, 375, 610, 360
Me.Refresh
End Sub
'NewWidth是你要显示出来图像的宽度
'ColorOne是其中的一种颜色,你可以自行设置
Private Function ShowBitmap(hdc As Long, X_Start As Long, Y_Start As Long, NewWidth As Long, NewHeight As Long) As Boolean
Dim Bytes As Long
Dim BmpInfo As BITMAPINFO
With BmpInfo.bmiHeader
.biBitCount = 24
.biCompression = 0
.biPlanes = 1
.biSize = Len(BmpInfo.bmiHeader)
.biWidth = 120
.biHeight = 72
End With
StretchDIBits hdc, X_Start, Y_Start, NewWidth, NewHeight, 0, 0, 120, 72, ImageData(0), BmpInfo, DIB_RGB_COLORS, vbSrcCopy
'SetDIBitsToDevice hdc, 100, 0, NewWidth, NewHeight, 0, 0, 0, NewHeight, ImageData(0), BmpInfo, DIB_RGB_COLORS
End Function
Private Sub Form_Load()
Me.AutoRedraw = True
End Sub
--------------------编程问答-------------------- 各位分析的很透彻,我已经使用一种方法显示在界面上了,但最近又不知道如何存储成图片,图片的格式无所谓了,我发我调好的程序贴出来,大家再帮帮忙看怎么才能在我这程序的基础上把图片存储下来呢?
'Private Const BI_RGB = 0&
'Private Const DIB_RGB_COLORS = 0
Private Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
'rgbReserved As Byte
End Type
Private Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Private Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors As RGBQUAD
End Type
Private Declare Function StretchDIBits Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal wSrcWidth As Long, ByVal wSrcHeight As Long, lpBits As Any, lpBitsInfo As BITMAPINFO, ByVal wUsage As Long, ByVal dwRop As Long) As Long
Private Declare Function SetDIBitsToDevice Lib "gdi32" (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, ByVal dx As Long, ByVal dy As Long, ByVal SrcX As Long, ByVal SrcY As Long, ByVal Scan As Long, ByVal NumScans As Long, Bits As Any, BitsInfo As BITMAPINFO, ByVal wUsage As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Dim ImageData(120 * 72&) As RGBQUAD '模拟图像数据
Private Sub Command1_Click()
Dim Index As Long
For Index = 0 To 120 * 72&
'ImageData(Index).rgbRed = Rnd * 255 '这里是模拟图像数据,我假定图像高度是300像素
ImageData(Index).rgbGreen = Rnd * 255 '这里是模拟图像数据,我假定图像高度是300像素
'ImageData(Index).rgbBlue = Rnd * 255 '这里是模拟图像数据,我假定图像高度是300像素
Next
Dim Gray As Byte
'处理灰度图(区Green法)
For Index = 0 To 120 * 72&
Gray = ImageData(Index).rgbGreen
ImageData(Index).rgbRed = Gray
ImageData(Index).rgbBlue = Gray
Next
ShowBitmap Me.hdc, 645, 375, 610, 360
Me.Refresh
End Sub
'NewWidth是你要显示出来图像的宽度
'ColorOne是其中的一种颜色,你可以自行设置
Private Function ShowBitmap(hdc As Long, X_Start As Long, Y_Start As Long, NewWidth As Long, NewHeight As Long) As Boolean
Dim Bytes As Long
Dim BmpInfo As BITMAPINFO
With BmpInfo.bmiHeader
.biBitCount = 24
.biCompression = 0
.biPlanes = 1
.biSize = Len(BmpInfo.bmiHeader)
.biWidth = 120
.biHeight = 72
End With
StretchDIBits hdc, X_Start, Y_Start, NewWidth, NewHeight, 0, 0, 120, 72, ImageData(0), BmpInfo, DIB_RGB_COLORS, vbSrcCopy
'SetDIBitsToDevice hdc, 100, 0, NewWidth, NewHeight, 0, 0, 0, NewHeight, ImageData(0), BmpInfo, DIB_RGB_COLORS
End Function
Private Sub Form_Load()
Me.AutoRedraw = True
End Sub
--------------------编程问答-------------------- 怎么发两次了........... --------------------编程问答-------------------- SavePicture Me.Image, "c:\dd.bmp" --------------------编程问答-------------------- SavePicture Me.Image, "c:\dd.bmp"
这语句不行啊!是把整个界面都保存下来了,我只要保存图片啊! --------------------编程问答-------------------- 把你的图像画picture控件中,调整控件大小等于图片大小,再保存即可。
1、添加一个picture控件到窗体中,命名为pic, AutoRedraw = True;
2、修改StretchDIBits hdc, X_Start...中hdc为pic.hdc;
3、画完后pic.width=图片宽度,pic.height=图片高度;
4、SavePicture pic.Image, "c:\dd.bmp"
--------------------编程问答-------------------- 简单的方法就是用 SavePicture 保存图片,如果你想提高效率或研究 BMP 文件格式,你可以看看我的这个范例,里面有BMP文件格式详细的说明和过程。
http://download.csdn.net/detail/SupermanKing/427319 --------------------编程问答--------------------
看我5楼的回复, 把图片显示在picture控件里, 不要忘记设置picture的autredraw=true, 在画完点之后,
调用picture.refresh显示图片, 然后就可以用savepicture picture.image...保存bmp了
补充:VB , API