vb中接受到数据采集卡的数据,8位宽度的,我把他存储到数组中,现在需要把数组中的数据显示成灰度图,灰度图的宽度和高度都已知,这要怎么做啊,最好能给个程序哦,我刚做VB不久还很多都没接触到哦!谢谢各位了!!

解决方案 »

  1.   

    这个得看你的数据是有符号的还是无符号的了. VB6的integer是有符号的, 超过32767就变成负数了
      

  2.   

    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这样的函数取出内存图像数据运算,然后将运算过的数据放回去显示。
      

  3.   


    抱歉,看错了,你的数据是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)的算法即可
        
      

  4.   

    上面忘记交代一句了, 请将picture控件的scalemode设为pixel, 可以去控件属性里面找
      

  5.   

    各位分析的很透彻,我已经使用一种方法显示在界面上了,但最近又不知道如何存储成图片,图片的格式无所谓了,我发我调好的程序贴出来,大家再帮帮忙看怎么才能在我这程序的基础上把图片存储下来呢?
    '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 FunctionPrivate Sub Form_Load()
    Me.AutoRedraw = TrueEnd Sub
      

  6.   

    各位分析的很透彻,我已经使用一种方法显示在界面上了,但最近又不知道如何存储成图片,图片的格式无所谓了,我发我调好的程序贴出来,大家再帮帮忙看怎么才能在我这程序的基础上把图片存储下来呢?
    '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 FunctionPrivate Sub Form_Load()
    Me.AutoRedraw = TrueEnd Sub
      

  7.   

    SavePicture Me.Image, "c:\dd.bmp"
      

  8.   

    SavePicture Me.Image, "c:\dd.bmp"
    这语句不行啊!是把整个界面都保存下来了,我只要保存图片啊!
      

  9.   

    把你的图像画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"
      

  10.   

    简单的方法就是用 SavePicture 保存图片,如果你想提高效率或研究 BMP 文件格式,你可以看看我的这个范例,里面有BMP文件格式详细的说明和过程。
    http://download.csdn.net/detail/SupermanKing/427319
      

  11.   


    看我5楼的回复, 把图片显示在picture控件里, 不要忘记设置picture的autredraw=true, 在画完点之后,
    调用picture.refresh显示图片, 然后就可以用savepicture picture.image...保存bmp了