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

fxyfx 2011-03-10 05:34:45
RT,Point的方式太慢了,有没有其他办法能快速的保存呢?
...全文
1026 44 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
44 条回复
切换为时间正序
请发表友善的回复…
发表回复
fxyfx 2011-03-14
  • 打赏
  • 举报
回复
恩,周六周日没上网,没有回复!
同意楼上,现在也我是这么做的,定义一个三维数组,用GetDIBits这个函数取点,第一维是蓝,第二位是绿,第三维是红。现在结贴了
zjl1234567 2011-03-12
  • 打赏
  • 举报
回复
VB区高手已经不在。这个问题我3年前遇到过。而当时参考的是一个叫“zy910”的大大5年前的帖子。

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

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

使用GetDIBits(设备无关)或GetBitmapBits(设备相关)函数就能得到整个图像的像素了
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
打开的BMP就是24位的图片,也是每个像素也是占2个字节!
andy95800 2011-03-11
  • 打赏
  • 举报
回复
那就跟图像的色深有关系了 建议你拿个标准的24位真彩bmp试试
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
十分感谢楼上的代码,不过我现在也需求jpg文件,也可以打开后再保存成bmp格式然后再处理!

现在在困惑的是GetBitmapBits取到的结果怎么跟大家说的不一样!
无·法 2011-03-11
  • 打赏
  • 举报
回复
如果是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
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
楼上的,是表示用几位吧?
lyserver 2011-03-11
  • 打赏
  • 举报
回复
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成员表示每像素用几个字节来表示。
andy95800 2011-03-11
  • 打赏
  • 举报
回复
Dim b() As Byte
andy95800 2011-03-11
  • 打赏
  • 举报
回复
自己试试就行了 对你来说问题不大了
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
b()定义的是字节数组
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
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)

代码就是这样的
andy95800 2011-03-11
  • 打赏
  • 举报
回复
那就只能看你代码说话了,变量声明不同 代码不同可能都有不同的结果
t=timer
这里t的类型不同 取得的值的精度也不同,可能一样的道理
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
哦,感谢楼上,现在我主要是想知道为什么我取出来的数组是每个点占两位,会不会有其他可能?
andy95800 2011-03-11
  • 打赏
  • 举报
回复
要想弄明白 你先看看你能不能成功复制一张图吧 如果按你的2位一点来打印
andy95800 2011-03-11
  • 打赏
  • 举报
回复
                  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)就是直观的各个点了
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
哦,有一点,我PictureBox的ScaleMode是Pixel
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
我用PictureBox打开的,一个BMP文件,一个JPG文件,两个大小一样,所得数组位数一样,我重新用PSet打印到另外一个图片上,只打印红色,也没错。
然后我打开了另外一张比较大的BMP文件,每个点也是占两位,打印红色出来也没错,所以我就比较奇怪。
andy95800 2011-03-11
  • 打赏
  • 举报
回复
BMP都是用RGB表示图像像素 每个点只占两位 的结论哪里得来的 分析错了吧
fxyfx 2011-03-11
  • 打赏
  • 举报
回复
可根据我取出来的数组,每个点只占两位,前面是红色,后面是黑色。还会有其他情况吗?比如1个,4个之类的。如果是这些,每位表示什么意思呢?
加载更多回复(24)

1,488

社区成员

发帖
与我相关
我的任务
社区描述
VB API
社区管理员
  • API
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧