请问,如何把一张图片每个点的像素保存为一个数组?

时间:2021-01-23 22:15:17
    RT,Point的方式太慢了,有没有其他办法能快速的保存呢?

46 个解决方案

#1


用api函数可能快点

#2


速度是一样的,都需要双重循环,逐点遍历

#3


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

#4


使用GetBitmapBits API函数

#5


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

#6


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

#7


如果是一次性比较那速度提升空间应该不大,如果是需要反复比较 那么可以考虑二进制方式读入图像数据并用数组保存图像点阵

#8


GetBitmapBits 是右下角->左上角

#9


感谢楼上,是反复比较!

请教“二进制方式读入图像数据并用数组保存图像点阵”是怎么样一种过程?能给点示例代码吗?或者说下流程也好。

另外我刚才试了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)
请问是以上代码有什么问题?

#10


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

#11


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

#12



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 Long

Private 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

#13


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

#14


jpg等picture能显示的图我一般用picture控件读入 再GetBitmapBits 
png比较麻烦了,要么加转换的类 要么通过webbrowser显示出来copy到picture控件里

其实你用GetBitmapBits 得到的b()就已经是图像点阵的雏形了 只不过需要进行一下RGB转换
不过由b()得到的新RGB数组的第一个像素点是左上角开始的

#15


感谢楼上,刚才我看错了,确实取出来了,十分感谢。

#16


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

#17


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

#18


可根据我取出来的数组,每个点只占两位,前面是红色,后面是黑色。还会有其他情况吗?比如1个,4个之类的。如果是这些,每位表示什么意思呢?

#19


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

#20


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

#21


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

#22


                  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)就是直观的各个点了

#23


要想弄明白 你先看看你能不能成功复制一张图吧 如果按你的2位一点来打印

#24


哦,感谢楼上,现在我主要是想知道为什么我取出来的数组是每个点占两位,会不会有其他可能?

#25


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

#26


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)

代码就是这样的

#27


b()定义的是字节数组

#28


自己试试就行了 对你来说问题不大了

#29


Dim b() As Byte

#30


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成员表示每像素用几个字节来表示。

#31


楼上的,是表示用几位吧?

#32


如果是bmp格式的话我这里有个直接读取的方法。

下面代码是直接将bmp图片读取并显示到picturebox中的,稍稍修改下就是你要的了。

窗体form1代码:

'添加一个picturebox1,按钮command1,防止一个bmp文件 c:\1.bmp
Option Explicit

Dim 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 Integer

Private 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 Sub

Sub 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 Sub

Sub 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 Sub

Sub 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 Sub


module模块代码:
Option Explicit

Public 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 Type

Public Type rgbw
    b As Byte
    g As Byte
    r As Byte
    w As Byte
End Type

#33


十分感谢楼上的代码,不过我现在也需求jpg文件,也可以打开后再保存成bmp格式然后再处理!

现在在困惑的是GetBitmapBits取到的结果怎么跟大家说的不一样!

#34


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

#35


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

#36


如果要读取的文件类型是固定的几个,并且对效率要求高,那么也可以自己解析这几种文件格式.

以下是BMP,JPG,PNG的文件结构,给你参考一下:

BMP文件格式详解

JPEG文件格式详解

PNG文件格式详解

#37


哎,找到问题了,我的屏幕不知道什么时候被设置成16位了,现在取出来是一个点4个字节,感谢大家

#38


引用 12 楼 lyserver 的回复:
VB code

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 A……


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

#39


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

#40


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

#41


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

#42


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

#43


VB区高手已经不在。这个问题我3年前遇到过。而当时参考的是一个叫“zy910”的大大5年前的帖子。

楼主去补习一下设备无关位图和设备相关位图的知识吧。

另外其实不用管文件的格式。用stdpicture对象(也可用picturebox控件),可直接加载常见图像,然后

使用GetDIBits(设备无关)或GetBitmapBits(设备相关)函数就能得到整个图像的像素了

#44


该回复于2011-03-14 08:55:07被版主删除

#45


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

#46


我想求C语言的方法怎么做??大神们!!!

#1


用api函数可能快点

#2


速度是一样的,都需要双重循环,逐点遍历

#3


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

#4


使用GetBitmapBits API函数

#5


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

#6


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

#7


如果是一次性比较那速度提升空间应该不大,如果是需要反复比较 那么可以考虑二进制方式读入图像数据并用数组保存图像点阵

#8


GetBitmapBits 是右下角->左上角

#9


感谢楼上,是反复比较!

请教“二进制方式读入图像数据并用数组保存图像点阵”是怎么样一种过程?能给点示例代码吗?或者说下流程也好。

另外我刚才试了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)
请问是以上代码有什么问题?

#10


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

#11


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

#12



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 Long

Private 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

#13


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

#14


jpg等picture能显示的图我一般用picture控件读入 再GetBitmapBits 
png比较麻烦了,要么加转换的类 要么通过webbrowser显示出来copy到picture控件里

其实你用GetBitmapBits 得到的b()就已经是图像点阵的雏形了 只不过需要进行一下RGB转换
不过由b()得到的新RGB数组的第一个像素点是左上角开始的

#15


感谢楼上,刚才我看错了,确实取出来了,十分感谢。

#16


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

#17


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

#18


可根据我取出来的数组,每个点只占两位,前面是红色,后面是黑色。还会有其他情况吗?比如1个,4个之类的。如果是这些,每位表示什么意思呢?

#19


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

#20


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

#21


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

#22


                  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)就是直观的各个点了

#23


要想弄明白 你先看看你能不能成功复制一张图吧 如果按你的2位一点来打印

#24


哦,感谢楼上,现在我主要是想知道为什么我取出来的数组是每个点占两位,会不会有其他可能?

#25


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

#26


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)

代码就是这样的

#27


b()定义的是字节数组

#28


自己试试就行了 对你来说问题不大了

#29


Dim b() As Byte

#30


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成员表示每像素用几个字节来表示。

#31


楼上的,是表示用几位吧?

#32


如果是bmp格式的话我这里有个直接读取的方法。

下面代码是直接将bmp图片读取并显示到picturebox中的,稍稍修改下就是你要的了。

窗体form1代码:

'添加一个picturebox1,按钮command1,防止一个bmp文件 c:\1.bmp
Option Explicit

Dim 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 Integer

Private 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 Sub

Sub 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 Sub

Sub 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 Sub

Sub 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 Sub


module模块代码:
Option Explicit

Public 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 Type

Public Type rgbw
    b As Byte
    g As Byte
    r As Byte
    w As Byte
End Type

#33


十分感谢楼上的代码,不过我现在也需求jpg文件,也可以打开后再保存成bmp格式然后再处理!

现在在困惑的是GetBitmapBits取到的结果怎么跟大家说的不一样!

#34


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

#35


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

#36


如果要读取的文件类型是固定的几个,并且对效率要求高,那么也可以自己解析这几种文件格式.

以下是BMP,JPG,PNG的文件结构,给你参考一下:

BMP文件格式详解

JPEG文件格式详解

PNG文件格式详解

#37


哎,找到问题了,我的屏幕不知道什么时候被设置成16位了,现在取出来是一个点4个字节,感谢大家

#38


引用 12 楼 lyserver 的回复:
VB code

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 A……


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

#39


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

#40


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

#41


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

#42


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

#43


VB区高手已经不在。这个问题我3年前遇到过。而当时参考的是一个叫“zy910”的大大5年前的帖子。

楼主去补习一下设备无关位图和设备相关位图的知识吧。

另外其实不用管文件的格式。用stdpicture对象(也可用picturebox控件),可直接加载常见图像,然后

使用GetDIBits(设备无关)或GetBitmapBits(设备相关)函数就能得到整个图像的像素了

#44


该回复于2011-03-14 08:55:07被版主删除

#45


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

#46


我想求C语言的方法怎么做??大神们!!!