RT,Point的方式太慢了,有没有其他办法能快速的保存呢?

解决方案 »

  1.   

    使用GetPixel来读取每个点的颜色
      

  2.   

    To sysdzw,请问用哪个API函数可以做到?
    To Veron_04, GetPixel和Point速度差不多,快不了多少!
    To lyserver, 这个只能处理BMP文件吧,请问有能够处理其他格式比如jpg,png的方法吗?
      

  3.   

    另外To lyserver,这个函数取到点以后,数组是怎么样一种格式?是和图片一样的从左到右从上到下的按点像素存储的吗?
      

  4.   

    GetBitmapBits 是右下角->左上角
      

  5.   

    感谢楼上,是反复比较!请教“二进制方式读入图像数据并用数组保存图像点阵”是怎么样一种过程?能给点示例代码吗?或者说下流程也好。另外我刚才试了GetBitmapBits,用PictureBox加载一张图片,然后用这个函数取,数组里面全是0,用法如下:
        Dim map As BitMap
        GetObject p.Image, Len(map), map
        ReDim b( map.bmWidthBytes * map.bmHeight- 1)
        GetBitmapBits p.Image, map.bmWidthBytes * map.bmHeight, b(0)
    请问是以上代码有什么问题?
      

  6.   

    哦,知道了,是我打开的是jpg图像!
      

  7.   

    请问类似jpg和Png格式的图像应该怎么处理?
      

  8.   


    Private Declare Function GetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As Long
    Private Declare Function SetBitmapBits Lib "gdi32" (ByVal hBitmap As Long, ByVal dwCount As Long, lpBits As Any) As LongPrivate Sub Command1_Click()
        Dim lpBits() As Byte
        Dim hBitmap, dwCount As Long, i As Long
        Dim nWidth As Long, nHeight As Long
        
        '以下代码取图像的像素数组,每3个字节表示一个像素
        hBitmap = Me.Picture1.Picture.Handle
        dwCount = GetBitmapBits(hBitmap, 0, ByVal 0&)
        ReDim lpBits(dwCount - 1)
        GetBitmapBits hBitmap, dwCount, lpBits(0)
        
        '以下代码把图像中的第二行的前50个像素的颜色设为红色
        nWidth = Me.ScaleX(Me.Picture1.Picture.Width, vbHimetric, vbPixels)
        For i = nWidth * 3 - 1 To nWidth * 3 + 50 Step 3
            lpBits(i) = 255
            lpBits(i + 1) = 0
            lpBits(i + 2) = 0
        Next
        SetBitmapBits hBitmap, dwCount, lpBits(0)
        Me.Picture1.Refresh
    End Sub
      

  9.   

    png需要使用GDI+渲染到GDI对象中。
      

  10.   

    jpg等picture能显示的图我一般用picture控件读入 再GetBitmapBits 
    png比较麻烦了,要么加转换的类 要么通过webbrowser显示出来copy到picture控件里其实你用GetBitmapBits 得到的b()就已经是图像点阵的雏形了 只不过需要进行一下RGB转换
    不过由b()得到的新RGB数组的第一个像素点是左上角开始的
      

  11.   

    另外的问题是,现在需要逐点对像素进行操作,请问楼上几位大侠能告诉我GetBitmapBits取出来的数据的格式是怎么样的?每个点占几位?这几位各表示什么?
      

  12.   

    b()里连续3个元素代表一个点,分别代表 R G B 的值 第一个点是左上角
      

  13.   

    BMP都是用RGB表示图像像素  每个点只占两位 的结论哪里得来的 分析错了吧
      

  14.   

        我用PictureBox打开的,一个BMP文件,一个JPG文件,两个大小一样,所得数组位数一样,我重新用PSet打印到另外一个图片上,只打印红色,也没错。
        然后我打开了另外一张比较大的BMP文件,每个点也是占两位,打印红色出来也没错,所以我就比较奇怪。
      

  15.   

    哦,有一点,我PictureBox的ScaleMode是Pixel
      

  16.   

                      GetObject Picture1.Image, Len(PicInfo), PicInfo
                      BytesPerPixel = PicInfo.bmBitsPixel \ 8
                      Dim pp() As Long
                      ReDim pp(PicInfo.bmWidth - 1, PicInfo.bmHeight - 1)
                      For i = 0 To UBound(PicBits) \ BytesPerPixel - 1
                              b = PicBits(i * BytesPerPixel + 1)
                              G = PicBits(i * BytesPerPixel + 2)
                              R = PicBits(i * BytesPerPixel + 3)
                              k = Int(i / PicInfo.bmHeight)
                              j = i - k * PicInfo.bmHeight
                              pp(j, k) = RGB(R, G, b)
                      Next i
    pp(j, k)就是直观的各个点了
      

  17.   

    那就只能看你代码说话了,变量声明不同 代码不同可能都有不同的结果
    t=timer 
    这里t的类型不同 取得的值的精度也不同,可能一样的道理
      

  18.   

    Dim map As BitMap
    GetObject p.Image, Len(map), map
    ReDim b( map.bmWidthBytes * map.bmHeight- 1)
    GetBitmapBits p.Image, map.bmWidthBytes * map.bmHeight, b(0)代码就是这样的
      

  19.   

    Private Type BITMAP '14 bytes
            bmType As Long
            bmWidth As Long
            bmHeight As Long
            bmWidthBytes As Long
            bmPlanes As Integer
            bmBitsPixel As Integer
            bmBits As Long
    End Type
    以上结构中bmBitsPixel成员表示每像素用几个字节来表示。
      

  20.   

    如果是bmp格式的话我这里有个直接读取的方法。下面代码是直接将bmp图片读取并显示到picturebox中的,稍稍修改下就是你要的了。窗体form1代码:'添加一个picturebox1,按钮command1,防止一个bmp文件 c:\1.bmp
    Option ExplicitDim bfh As BitFileHeader
    Dim colornumber As Byte, thisrgbw As rgbw, thiscolor As Long
    Dim x As Long, y As Long
    Dim cols As Integer, rows As IntegerPrivate Sub Command1_Click()
        Dim strInfo As String
        
        Open "c:\1.bmp" For Binary As #1
        Get #1, 1, bfh    strInfo = "文件参数:" & vbCrLf & vbCrLf & _
                    "bfsize = " & bfh.bfsize & vbCrLf & _
                    "bfoffbits = " & bfh.bfoffbits & vbCrLf & _
                    "biwidth = " & bfh.biwidth & vbCrLf & _
                    "biheight = " & bfh.biheight & vbCrLf & _
                    "调色板数 = " & bfh.biplanes & vbCrLf & _
                    "颜色位数 = " & bfh.bibitcount & vbCrLf & _
                    "bicompress = " & bfh.bicompress & vbCrLf & _
                    "bisizeimage = " & bfh.bisizeimage & vbCrLf & _
                    "bixpixelpermeter = " & bfh.bixpixelpermeter & vbCrLf & _
                    "biypixelspermeter = " & bfh.biypixelspermeter & vbCrLf & _
                    "bilrused = " & bfh.bilrused & vbCrLf & _
                    "biclrinportant = " & bfh.biclrinportant
                    
        MsgBox strInfo    Picture1.Width = bfh.biwidth
        Picture1.Height = bfh.biheight
        DoEvents
            
        Select Case bfh.bibitcount
            Case 1
                    Call deal2bmp
            Case 4
                    Call deal16bmp
            Case 8
                    Call deal256bmp
            Case 24
                    Call deal24bitbmp
        End Select
        Close #1
    End Sub
    Sub deal2bmp()
        Dim i As Integer, thisbit As Integer
        cols = (bfh.biwidth + 7) \ 8 '八个点共一个字节
        cols = IIf(cols Mod 4 = 0, cols, (cols \ 4 + 1) * 4) '凑成4有倍数
        rows = bfh.biheight
        For y = 0 To rows - 1
            For x = 0 To cols - 1
                Get #1, bfh.bfoffbits + 1 + y * cols + x, colornumber
                For i = 7 To 0 Step -1
                    thisbit = colornumber \ (2 ^ i) Mod 2 '滤出一个字节中的某一位作为一个点的颜色号
                    Get #1, 55 + thisbit * 4, thisrgbw
                    
                    thiscolor = RGB(thisrgbw.r, thisrgbw.g, thisrgbw.b)
                    If x < (bfh.biwidth + 7) \ 8 Then
                        Picture1.PSet (8 * x + 7 - i, rows - 1 - y), thiscolor
                    End If
                Next i
            Next x
        Next y
    End SubSub deal16bmp()
        cols = (bfh.biwidth + 1) \ 2 '两个点共一个字节
        cols = IIf(cols Mod 4 = 0, cols, (cols \ 4 + 1) * 4) '凑成4有倍数
        rows = bfh.biheight
        For y = 0 To rows - 1
            For x = 0 To cols - 1
                Get #1, bfh.bfoffbits + 1 + y * cols + x, colornumber
                Get #1, 55 + (colornumber \ 16) * 4, thisrgbw '读取左4位作为第一个点的颜色号
                thiscolor = RGB(thisrgbw.r, thisrgbw.g, thisrgbw.b)
                If x < (bfh.biwidth + 1) \ 2 Then Picture1.PSet (2 * x, rows - 1 - y), thiscolor
                
                Get #1, 55 + (colornumber Mod 16) * 4, thisrgbw '读取右4位作为第二个点的颜色号
                thiscolor = RGB(thisrgbw.r, thisrgbw.g, thisrgbw.b)
                If x < (bfh.biwidth + 1) \ 2 Then Picture1.PSet (2 * x + 1, rows - 1 - y), thiscolor
            Next x
        Next y
    End SubSub deal256bmp()
        cols = IIf(bfh.biwidth Mod 4 = 0, bfh.biwidth, (bfh.biwidth \ 4 + 1) * 4) '每点占一个字节,每行字节数凑成4的倍数
        rows = bfh.biheight
        For y = 0 To rows - 1
            For x = 0 To cols - 1
                Get #1, bfh.bfoffbits + 1 + y * cols + x, colornumber
                Get #1, 55 + colornumber * 4, thisrgbw
                thiscolor = RGB(thisrgbw.r, thisrgbw.g, thisrgbw.b)
                If x < bfh.biwidth Then Picture1.PSet (x, rows - 1 - y), thiscolor
            Next x
        Next y
    End SubSub deal24bitbmp()
        Dim r As Byte, g As Byte, b As Byte
        cols = IIf(3 * bfh.biwidth Mod 4 = 0, 3 * bfh.biwidth, (3 * bfh.biwidth \ 4 + 1) * 4) '每点占三个字节,每行字节数凑成4的倍数
        rows = bfh.biheight
        For y = 0 To rows - 1
            For x = 0 To cols - 1
                Get #1, bfh.bfoffbits + 1 + y * cols + x, thisrgbw
                thiscolor = RGB(thisrgbw.r, thisrgbw.g, thisrgbw.b)
                If x Mod 3 = 0 And x < 3 * bfh.biwidth Then Picture1.PSet (x \ 3, rows - 1 - y), thiscolor
            Next x
        Next y
    End Submodule模块代码:
    Option ExplicitPublic Type BitFileHeader
        bftype As String * 2 '2
        bfsize As Long '4
        bfreserved1 As Integer '2
        bfreserved2 As Integer '2
        bfoffbits As Long '4
        bisize As Long '4
        biwidth As Long '4
        biheight As Long '4
        biplanes As Integer '2
        bibitcount As Integer '2
        bicompress As Long '4
        bisizeimage As Long '4
        bixpixelpermeter As Long '4
        biypixelspermeter As Long '4
        bilrused As Long '4
        biclrinportant As Long '4
    End TypePublic Type rgbw
        b As Byte
        g As Byte
        r As Byte
        w As Byte
    End Type
      

  21.   

    十分感谢楼上的代码,不过我现在也需求jpg文件,也可以打开后再保存成bmp格式然后再处理!现在在困惑的是GetBitmapBits取到的结果怎么跟大家说的不一样!
      

  22.   

    那就跟图像的色深有关系了  建议你拿个标准的24位真彩bmp试试
      

  23.   

    打开的BMP就是24位的图片,也是每个像素也是占2个字节!
      

  24.   

    如果要读取的文件类型是固定的几个,并且对效率要求高,那么也可以自己解析这几种文件格式.以下是BMP,JPG,PNG的文件结构,给你参考一下:BMP文件格式详解JPEG文件格式详解PNG文件格式详解
      

  25.   


       dwCount = GetBitmapBits(hBitmap, 0, ByVal 0&)
        ReDim lpBits(dwCount - 1)
        GetBitmapBits hBitmap, dwCount, lpBits(0)
    这3行可以用一行来写吗?
    第一次调用GetBitmapBits只是用来获得字节数的?
      

  26.   

    还有
    nWidth = Me.ScaleX(Me.Picture1.Picture.Width, vbHimetric, vbPixels)
    这句啥意思?
    他和scalewidth有啥区别呢
      

  27.   

    第一次运行的 GetBitmapBits 是必须的 要么无法确定接收图像数组的大小
    或者不用GetBitmapBits换用getobject也行 不过要构造个BITMAP类型 
      

  28.   

    dwCount = GetBitmapBits(hBitmap, 0, ByVal 0&)
    当GetBitmapBits遇到第2个参数为0的时候,他还会看第3个参数吗?是不是就忽略第3个参数了?
      

  29.   

    dwCount = GetBitmapBits(hBitmap, 0, ByVal 0&)
    当GetBitmapBits遇到第2个参数为0的时候,他还会看第3个参数吗?是不是就忽略第3个参数了?
      

  30.   

    VB区高手已经不在。这个问题我3年前遇到过。而当时参考的是一个叫“zy910”的大大5年前的帖子。楼主去补习一下设备无关位图和设备相关位图的知识吧。另外其实不用管文件的格式。用stdpicture对象(也可用picturebox控件),可直接加载常见图像,然后使用GetDIBits(设备无关)或GetBitmapBits(设备相关)函数就能得到整个图像的像素了
      

  31.   

    恩,周六周日没上网,没有回复!
    同意楼上,现在也我是这么做的,定义一个三维数组,用GetDIBits这个函数取点,第一维是蓝,第二位是绿,第三维是红。现在结贴了