1,以人名和相关图片为例说明,数据库为Access,有如下字段:Name char,picture OLE object,FileLength Number。当为ms sql时,将picture改为lob即可。 2,示例包含control:commom dialog,picture,listbox。 源码如下: Option Explicit Private Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" (ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal wUnique As Long, ByVal lpTempFileName As String) As Long Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpBuffer As String) As Long Private Const MAX_PATH = 260 Private m_DBConn As ADODB.Connection Private Const BLOCK_SIZE = 10000 注释: Return a temporary file name. Private Function TemporaryFileName() As String Dim temp_path As String Dim temp_file As String Dim length As Long 注释: Get the temporary file path. temp_path = Space$(MAX_PATH) length = GetTempPath(MAX_PATH, temp_path) temp_path = Left$(temp_path, length) 注释: Get the file name. temp_file = Space$(MAX_PATH) GetTempFileName temp_path, "per", 0, temp_file TemporaryFileName = Left$(temp_file, InStr(temp_file, Chr$(0)) - 1) End Function Private Sub Form_Load() Dim db_file As String Dim rs As ADODB.Recordset 注释: Get the database file name. db_file = App.Path If Right$(db_file, 1) <> "" Then db_file = db_file & "" db_file = db_file & "dbpict.mdb" 注释: Open the database connection. Set m_DBConn = New ADODB.Connection m_DBConn.Open _ "Provider=Microsoft.Jet.OLEDB.4.0;" & _ "Data Source=" & db_file & ";" & _ "Persist Security Info=False" 注释: Get the list of people. Set rs = m_DBConn.Execute("SELECT Name FROM People ORDER BY Name", , adCmdText) Do While Not rs.EOF lstPeople.AddItem rs!Name rs.MoveNext Loop rs.Close Set rs = Nothing End Sub Private Sub Form_Resize() lstPeople.Height = ScaleHeight End Sub 注释: Display the clicked person. Private Sub lstPeople_Click() Dim rs As ADODB.Recordset Dim bytes() As Byte Dim file_name As String Dim file_num As Integer Dim file_length As Long Dim num_blocks As Long Dim left_over As Long Dim block_num As Long Dim hgt As Single picPerson.Visible = False Screen.MousePointer = vbHourglass DoEvents 注释: Get the record. Set rs = m_DBConn.Execute("SELECT * FROM People WHERE Name=注释:" & _ lstPeople.Text & "注释:", , adCmdText) If rs.EOF Then Exit Sub 注释: Get a temporary file name. file_name = TemporaryFileName() 注释: Open the file. file_num = FreeFile Open file_name For Binary As #file_num 注释: Copy the data into the file. file_length = rs!FileLength num_blocks = file_length / BLOCK_SIZE left_over = file_length Mod BLOCK_SIZE For block_num = 1 To num_blocks bytes() = rs!Picture.GetChunk(BLOCK_SIZE) Put #file_num, , bytes() Next block_num If left_over > 0 Then bytes() = rs!Picture.GetChunk(left_over) Put #file_num, , bytes() End If Close #file_num 注释: Display the picture file. picPerson.Picture = LoadPicture(file_name) picPerson.Visible = True Width = picPerson.Left + picPerson.Width + Width - ScaleWidth hgt = picPerson.Top + picPerson.Height + Height - ScaleHeight If hgt < 1440 Then hgt = 1440 Height = hgt Kill file_name Screen.MousePointer = vbDefault End Sub Private Sub mnuRecordAdd_Click() Dim rs As ADODB.Recordset Dim person_name As String Dim file_num As String Dim file_length As String Dim bytes() As Byte Dim num_blocks As Long Dim left_over As Long Dim block_num As Long person_name = InputBox("Name") If Len(person_name) = 0 Then Exit Sub dlgPicture.Flags = _ cdlOFNFileMustExist Or _ cdlOFNHideReadOnly Or _ cdlOFNExplorer dlgPicture.CancelError = True dlgPicture.Filter = "Graphics Files|*.bmp;*.ico;*.jpg;*.gif" On Error Resume Next dlgPicture.ShowOpen If Err.Number = cdlCancel Then Exit Sub ElseIf Err.Number <> 0 Then MsgBox "Error " & Format$(Err.Number) & _ " selecting file." & vbCrLf & Err.Description Exit Sub End If 注释: Open the picture file. file_num = FreeFile Open dlgPicture.FileName For Binary Access Read As #file_num file_length = LOF(file_num) If file_length > 0 Then num_blocks = file_length / BLOCK_SIZE left_over = file_length Mod BLOCK_SIZE Set rs = New ADODB.Recordset rs.CursorType = adOpenKeyset rs.LockType = adLockOptimistic rs.Open "Select Name, Picture, FileLength FROM People", m_DBConn rs.AddNew rs!Name = person_name rs!FileLength = file_length ReDim bytes(BLOCK_SIZE) For block_num = 1 To num_blocks Get #file_num, , bytes() rs!Picture.AppendChunk bytes() Next block_num If left_over > 0 Then ReDim bytes(left_over) Get #file_num, , bytes() rs!Picture.AppendChunk bytes() End If rs.Update Close #file_num lstPeople.AddItem person_name lstPeople.Text = person_name End If End Sub
注:写图片文件到数据库 Col为栏位名,ImgFile为要写到数据库的图片文件名,BockSize为每次写多少字节,缺省为每次写8K字节到数据库 Public Sub WriteDB(Col As ADODB.Field, ImgFile As String, Optional BlockSize As Long=8192) Dim byteData() As Byte, FileLength As Long, NumBlocks As Integer Dim LeftOver As Long, SourceFileNum As Integer, i As Integer SourceFileNum = FreeFile Open ImgFile For Binary As SourceFileNum FileLength = LOF(SourceFileNum) If FileLength > 50 Then NumBlocks = FileLength \ BlockSize LeftOver = FileLength Mod BlockSize ReDim byteData(LeftOver) Get SourceFileNum, , byteData() Col.AppendChunk byteData() ReDim byteData(BlockSize) For i = 1 To NumBlocks Get SourceFileNum, , byteData() Col.AppendChunk byteData() Next End If Close SourceFileNum End Sub ImgFile为从数据库读出数据写到磁盘的文件名,BlockSize为每次向文件写多少个字节,缺省为8K字节,当ReadDB=True,得到图片文件後,可以用LoadPicter(图片文件名)显示图片到PictureBox或Image框中. Public Function ReadDB(Col As ADODB.Field, ImgFile As String,Optional BlockSize As Long=8192) As Boolean Dim byteData() As Byte, NumBlocks As Integer Dim LeftOver As Long, DestFileNum As Integer, i As Integer Dim ColSize As Long On Error GoTo ErrRead ReadDB = False 'If Dir(ImgFile) <> "" Then Kill ImgFile DestFileNum = FreeFile Open ImgFile For Binary As #DestFileNum ColSize = Col.ActualSize NumBlocks = ColSize \ BlockSize LeftOver = ColSize Mod BlockSize ReDim byteData(LeftOver) byteData() = Col.GetChunk(LeftOver) Put DestFileNum, , byteData() ReDim byteData(BlockSize) For i = 1 To NumBlocks byteData() = Col.GetChunk(BlockSize) Put #DestFileNum, , byteData() Next If LOF(DestFileNum) > 200 Then ReadDB = True Close #DestFileNum Exit Function ErrRead: MsgBox "READ PICTURE ERR:" & Err.Number ReadDB = False Exit Function End Function//如果ReadDB=False则写文件失败。
可以试试用ADO来存储与读取图片:下面是我前段时间刚刚做的正确代码,希望对你有帮助。 option explicit Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpbuffer As String) As Long Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" (ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal wUnique As Long, ByVal lpTempFileName As String) As Long Public Function TemporaryFileName() As String Dim temp_path As String Dim temp_file As String Dim Length As Long '注释: Get the temporary file path. temp_path = Space$(MAX_PATH) Length = GetTempPath(MAX_PATH, temp_path) temp_path = Left$(temp_path, Length) '注释: Get the file name. temp_file = Space$(MAX_PATH) GetTempFileName temp_path, "per", 0, temp_file TemporaryFileName = Left$(temp_file, InStr(temp_file, Chr$(0)) - 1) End Function Dim bytes() As Byte '存储图片的空间 Dim file_length As Long '图片文件的长度 Dim num_blocks As Long '图片被分割的块数 Dim left_over As Long '图片被分割后的剩余大小 Dim block_num As Long Dim file_num As Integer Dim file_name As String '获取一个临时文件 Dim varchunk As Variant Dim filename As String '打开一个文件的名称 Const BLOCKSIZE = 4096 Const BLOCK_SIZE = 10000 Const BLOCK_PATH = 260 从数据库中读取图片: txtsql = "select * from tbl_picture where maptype= 'Background'" Set mrc = ExecuteSQL(txtsql, msgtext) file_name = TemporaryFileName() file_num = FreeFile Open file_name For Binary As #file_num file_length = mrc!FileLength num_blocks = file_length / BLOCK_SIZE left_over = file_length Mod BLOCK_SIZE
For block_num = 1 To num_blocks bytes() = mrc!Picture.GetChunk(BLOCK_SIZE) Put #file_num, , bytes() Next block_num If left_over > 0 Then varchunk = mrc.Fields(1).GetChunk(left_over) Put #file_num, , varchunk End If
Close #file_num Image1.Picture = LoadPicture(file_name) Kill file_name mrc.Close 往表Background中写图片数据: '打开一个图片 Private Sub cmd_backopen_Click() On Error GoTo error_open CommonDialog1.Filter = "Graphics Files|*.bmp;*.ico;*.jpg;*.gif" CommonDialog1.ShowOpen filename = CommonDialog1.filename If filename = "" Then Exit Sub End If PicAlarmMap.Picture = LoadPicture(filename) cmdAddDetector.Enabled = False cmdArea.Enabled = False Exit Sub error_open: MsgBox Err.Description CommonDialog1.filename = "" End Sub '将一个背景图片保存到数据库中 Private Sub cmd_backsave_Click() If filename = "" Then Exit Sub End If txtsql = "select * from tbl_picture" Set mrc = ExecuteSQL(txtsql, msgtext) If mrc.EOF = False Then txtsql = "delete from tbl_picture where name='Main'" Set mrc = ExecuteSQL(txtsql, msgtext) txtsql = "select * from tbl_picture " Set mrc = ExecuteSQL(txtsql, msgtext) End If mrc.AddNew file_num = FreeFile Open filename For Binary Access Read As #file_num FileLength = LOF(file_num) If FileLength = 0 Then Close #file_num
Exit Sub Else num_blocks = FileLength \ BLOCKSIZE left_over = FileLength Mod BLOCKSIZE 'rst.Fields(1).value = Null ReDim bytes(BLOCKSIZE) For block_num = 1 To num_blocks Get #file_num, , bytes() mrc.Fields(1).AppendChunk bytes() Next block_num ReDim bytes(left_over) Get file_num, , bytes() mrc.Fields(1).AppendChunk bytes() Close #file_num End If mrc.Fields(0) = "main" mrc.Fields(2) = FileLength mrc.Fields(3) = "Main" mrc.update MessageBox Me.hwnd, LanguageIni.GetIniKey("frmalarmmap", "str5"), "IDMS", &H0& cmdAddDetector.Enabled = True cmdArea.Enabled = True filename = "" End Sub 另外要说明的是: Background表中的字段一共有四个(name char(10),picture image,filelength long,maptype char(10)) 你只需要前面三个字段就可以了。第二个是装图片数据,第三个是图片的大小。
如何使用 ADO Stream 对象访问和修改 SQL Server BLOB 数据(也就是一般的图像在SQL中存储类型) http://support.microsoft.com/default.aspx?scid=kb;zh-cn;258038
Number。当为ms sql时,将picture改为lob即可。
2,示例包含control:commom dialog,picture,listbox。
源码如下:
Option Explicit Private Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" (ByVal lpszPath As
String, ByVal lpPrefixString As String, ByVal wUnique As Long, ByVal lpTempFileName As String) As Long
Private Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long,
ByVal lpBuffer As String) As Long
Private Const MAX_PATH = 260 Private m_DBConn As ADODB.Connection Private Const BLOCK_SIZE = 10000
注释: Return a temporary file name.
Private Function TemporaryFileName() As String
Dim temp_path As String
Dim temp_file As String
Dim length As Long 注释: Get the temporary file path.
temp_path = Space$(MAX_PATH)
length = GetTempPath(MAX_PATH, temp_path)
temp_path = Left$(temp_path, length) 注释: Get the file name.
temp_file = Space$(MAX_PATH)
GetTempFileName temp_path, "per", 0, temp_file
TemporaryFileName = Left$(temp_file, InStr(temp_file, Chr$(0)) - 1)
End Function
Private Sub Form_Load()
Dim db_file As String
Dim rs As ADODB.Recordset 注释: Get the database file name.
db_file = App.Path
If Right$(db_file, 1) <> "" Then db_file = db_file & ""
db_file = db_file & "dbpict.mdb" 注释: Open the database connection.
Set m_DBConn = New ADODB.Connection
m_DBConn.Open _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & db_file & ";" & _
"Persist Security Info=False" 注释: Get the list of people.
Set rs = m_DBConn.Execute("SELECT Name FROM People ORDER BY Name", , adCmdText)
Do While Not rs.EOF
lstPeople.AddItem rs!Name
rs.MoveNext
Loop rs.Close
Set rs = Nothing
End Sub
Private Sub Form_Resize()
lstPeople.Height = ScaleHeight
End Sub
注释: Display the clicked person.
Private Sub lstPeople_Click()
Dim rs As ADODB.Recordset
Dim bytes() As Byte
Dim file_name As String
Dim file_num As Integer
Dim file_length As Long
Dim num_blocks As Long
Dim left_over As Long
Dim block_num As Long
Dim hgt As Single picPerson.Visible = False
Screen.MousePointer = vbHourglass
DoEvents 注释: Get the record.
Set rs = m_DBConn.Execute("SELECT * FROM People WHERE Name=注释:" & _
lstPeople.Text & "注释:", , adCmdText)
If rs.EOF Then Exit Sub 注释: Get a temporary file name.
file_name = TemporaryFileName() 注释: Open the file.
file_num = FreeFile
Open file_name For Binary As #file_num 注释: Copy the data into the file.
file_length = rs!FileLength
num_blocks = file_length / BLOCK_SIZE
left_over = file_length Mod BLOCK_SIZE For block_num = 1 To num_blocks
bytes() = rs!Picture.GetChunk(BLOCK_SIZE)
Put #file_num, , bytes()
Next block_num If left_over > 0 Then
bytes() = rs!Picture.GetChunk(left_over)
Put #file_num, , bytes()
End If Close #file_num 注释: Display the picture file.
picPerson.Picture = LoadPicture(file_name)
picPerson.Visible = True Width = picPerson.Left + picPerson.Width + Width - ScaleWidth
hgt = picPerson.Top + picPerson.Height + Height - ScaleHeight
If hgt < 1440 Then hgt = 1440
Height = hgt Kill file_name
Screen.MousePointer = vbDefault
End Sub Private Sub mnuRecordAdd_Click()
Dim rs As ADODB.Recordset
Dim person_name As String
Dim file_num As String
Dim file_length As String
Dim bytes() As Byte
Dim num_blocks As Long
Dim left_over As Long
Dim block_num As Long person_name = InputBox("Name")
If Len(person_name) = 0 Then Exit Sub dlgPicture.Flags = _
cdlOFNFileMustExist Or _
cdlOFNHideReadOnly Or _
cdlOFNExplorer
dlgPicture.CancelError = True
dlgPicture.Filter = "Graphics Files|*.bmp;*.ico;*.jpg;*.gif" On Error Resume Next
dlgPicture.ShowOpen
If Err.Number = cdlCancel Then
Exit Sub
ElseIf Err.Number <> 0 Then
MsgBox "Error " & Format$(Err.Number) & _
" selecting file." & vbCrLf & Err.Description
Exit Sub
End If 注释: Open the picture file.
file_num = FreeFile
Open dlgPicture.FileName For Binary Access Read As #file_num file_length = LOF(file_num)
If file_length > 0 Then
num_blocks = file_length / BLOCK_SIZE
left_over = file_length Mod BLOCK_SIZE Set rs = New ADODB.Recordset
rs.CursorType = adOpenKeyset
rs.LockType = adLockOptimistic
rs.Open "Select Name, Picture, FileLength FROM People", m_DBConn rs.AddNew
rs!Name = person_name
rs!FileLength = file_length ReDim bytes(BLOCK_SIZE)
For block_num = 1 To num_blocks
Get #file_num, , bytes()
rs!Picture.AppendChunk bytes()
Next block_num If left_over > 0 Then
ReDim bytes(left_over)
Get #file_num, , bytes()
rs!Picture.AppendChunk bytes()
End If rs.Update
Close #file_num lstPeople.AddItem person_name
lstPeople.Text = person_name
End If
End Sub
Col为栏位名,ImgFile为要写到数据库的图片文件名,BockSize为每次写多少字节,缺省为每次写8K字节到数据库
Public Sub WriteDB(Col As ADODB.Field, ImgFile As String, Optional BlockSize As Long=8192)
Dim byteData() As Byte, FileLength As Long, NumBlocks As Integer
Dim LeftOver As Long, SourceFileNum As Integer, i As Integer SourceFileNum = FreeFile
Open ImgFile For Binary As SourceFileNum
FileLength = LOF(SourceFileNum)
If FileLength > 50 Then
NumBlocks = FileLength \ BlockSize
LeftOver = FileLength Mod BlockSize ReDim byteData(LeftOver)
Get SourceFileNum, , byteData()
Col.AppendChunk byteData()
ReDim byteData(BlockSize)
For i = 1 To NumBlocks
Get SourceFileNum, , byteData()
Col.AppendChunk byteData()
Next
End If
Close SourceFileNum
End Sub
ImgFile为从数据库读出数据写到磁盘的文件名,BlockSize为每次向文件写多少个字节,缺省为8K字节,当ReadDB=True,得到图片文件後,可以用LoadPicter(图片文件名)显示图片到PictureBox或Image框中.
Public Function ReadDB(Col As ADODB.Field, ImgFile As String,Optional BlockSize As Long=8192) As Boolean
Dim byteData() As Byte, NumBlocks As Integer
Dim LeftOver As Long, DestFileNum As Integer, i As Integer
Dim ColSize As Long On Error GoTo ErrRead
ReadDB = False 'If Dir(ImgFile) <> "" Then Kill ImgFile DestFileNum = FreeFile
Open ImgFile For Binary As #DestFileNum ColSize = Col.ActualSize
NumBlocks = ColSize \ BlockSize
LeftOver = ColSize Mod BlockSize ReDim byteData(LeftOver)
byteData() = Col.GetChunk(LeftOver)
Put DestFileNum, , byteData()
ReDim byteData(BlockSize)
For i = 1 To NumBlocks
byteData() = Col.GetChunk(BlockSize)
Put #DestFileNum, , byteData()
Next
If LOF(DestFileNum) > 200 Then ReadDB = True
Close #DestFileNum
Exit Function ErrRead:
MsgBox "READ PICTURE ERR:" & Err.Number
ReadDB = False
Exit Function
End Function//如果ReadDB=False则写文件失败。
option explicit
Declare Function GetTempPath Lib "kernel32" Alias "GetTempPathA" (ByVal nBufferLength As Long, ByVal lpbuffer As String) As Long
Declare Function GetTempFileName Lib "kernel32" Alias "GetTempFileNameA" (ByVal lpszPath As String, ByVal lpPrefixString As String, ByVal wUnique As Long, ByVal lpTempFileName As String) As Long
Public Function TemporaryFileName() As String
Dim temp_path As String
Dim temp_file As String
Dim Length As Long
'注释: Get the temporary file path.
temp_path = Space$(MAX_PATH)
Length = GetTempPath(MAX_PATH, temp_path)
temp_path = Left$(temp_path, Length)
'注释: Get the file name.
temp_file = Space$(MAX_PATH)
GetTempFileName temp_path, "per", 0, temp_file
TemporaryFileName = Left$(temp_file, InStr(temp_file, Chr$(0)) - 1)
End Function
Dim bytes() As Byte '存储图片的空间
Dim file_length As Long '图片文件的长度
Dim num_blocks As Long '图片被分割的块数
Dim left_over As Long '图片被分割后的剩余大小
Dim block_num As Long
Dim file_num As Integer
Dim file_name As String '获取一个临时文件
Dim varchunk As Variant
Dim filename As String '打开一个文件的名称
Const BLOCKSIZE = 4096
Const BLOCK_SIZE = 10000
Const BLOCK_PATH = 260
从数据库中读取图片:
txtsql = "select * from tbl_picture where maptype= 'Background'"
Set mrc = ExecuteSQL(txtsql, msgtext)
file_name = TemporaryFileName()
file_num = FreeFile
Open file_name For Binary As #file_num
file_length = mrc!FileLength
num_blocks = file_length / BLOCK_SIZE
left_over = file_length Mod BLOCK_SIZE
For block_num = 1 To num_blocks
bytes() = mrc!Picture.GetChunk(BLOCK_SIZE)
Put #file_num, , bytes()
Next block_num If left_over > 0 Then
varchunk = mrc.Fields(1).GetChunk(left_over)
Put #file_num, , varchunk
End If
Close #file_num
Image1.Picture = LoadPicture(file_name)
Kill file_name
mrc.Close
往表Background中写图片数据:
'打开一个图片
Private Sub cmd_backopen_Click()
On Error GoTo error_open
CommonDialog1.Filter = "Graphics Files|*.bmp;*.ico;*.jpg;*.gif"
CommonDialog1.ShowOpen
filename = CommonDialog1.filename
If filename = "" Then
Exit Sub
End If
PicAlarmMap.Picture = LoadPicture(filename)
cmdAddDetector.Enabled = False
cmdArea.Enabled = False
Exit Sub
error_open:
MsgBox Err.Description
CommonDialog1.filename = ""
End Sub
'将一个背景图片保存到数据库中
Private Sub cmd_backsave_Click()
If filename = "" Then
Exit Sub
End If
txtsql = "select * from tbl_picture"
Set mrc = ExecuteSQL(txtsql, msgtext)
If mrc.EOF = False Then
txtsql = "delete from tbl_picture where name='Main'"
Set mrc = ExecuteSQL(txtsql, msgtext)
txtsql = "select * from tbl_picture "
Set mrc = ExecuteSQL(txtsql, msgtext)
End If
mrc.AddNew
file_num = FreeFile
Open filename For Binary Access Read As #file_num
FileLength = LOF(file_num)
If FileLength = 0 Then
Close #file_num
Exit Sub
Else
num_blocks = FileLength \ BLOCKSIZE
left_over = FileLength Mod BLOCKSIZE
'rst.Fields(1).value = Null
ReDim bytes(BLOCKSIZE)
For block_num = 1 To num_blocks
Get #file_num, , bytes()
mrc.Fields(1).AppendChunk bytes()
Next block_num
ReDim bytes(left_over)
Get file_num, , bytes()
mrc.Fields(1).AppendChunk bytes()
Close #file_num
End If
mrc.Fields(0) = "main"
mrc.Fields(2) = FileLength
mrc.Fields(3) = "Main"
mrc.update
MessageBox Me.hwnd, LanguageIni.GetIniKey("frmalarmmap", "str5"), "IDMS", &H0&
cmdAddDetector.Enabled = True
cmdArea.Enabled = True
filename = ""
End Sub
另外要说明的是:
Background表中的字段一共有四个(name char(10),picture image,filelength long,maptype char(10))
你只需要前面三个字段就可以了。第二个是装图片数据,第三个是图片的大小。
http://support.microsoft.com/default.aspx?scid=kb;zh-cn;258038
保存路径就可也。