Option Explicit Dim en As rdoEnvironment Dim Qd As rdoQuery Dim Cn As rdoConnection Dim Rs As rdoResultset Dim SQL As String Dim DataFile As Integer, Fl As Long, Chunks As Integer Dim Fragment As Integer, Chunk() As Byte, I As Integer Const ChunkSize As Integer = 16384Private Sub Form_Load() Set en = rdoEnvironments(0) Set Cn = en.OpenConnection(dsname:="", _ Connect:="UID=;PWD=;DATABASE=WorkDB;" _ & ""Driver={SQL Server};SERVER=Betav486", _ prompt:=rdDriverNoPrompt) Set Qd = Cn.CreateQuery("TestChunk", "Select * from Chunks Where PName = ?") End Sub Private Sub LoadFromFile_Click() ' ' 将文件定位并为该文件设置文件名。 ' With CommonDialog1 .Filter = "Pictures(*.bmp;*.ico)|*.bmp;*.ico" .ShowOpen FileName = .FileName End With End SubPrivate Sub ReadFromDB_Click() If Len(NameWanted) = 0 Then _ NameWanted = InputBox("Enter name wanted", "Animal") Qd(0) = NameWanted Set Rs = Qd.OpenResultset(rdOpenKeyset, rdConcurRowver) If Rs Is Nothing Or Rs.Updatable = False Then MsgBox "Can't open or write to result set" Exit Sub End If If Rs.EOF Then MsgBox "Can't find picture by that name" Exit Sub End If Description = Rs!Description DataFile = 1 Open "pictemp" For Binary Access Write As DataFile Fl = Rs!Photo.ColumnSize Chunks = Fl \ ChunkSize Fragment = Fl Mod ChunkSize --------------------------------------------------------- ReDim Chunk(Fragment) '这里初始化二进制数组。 -------------------------------------------------------- Chunk() = Rs!Photo.GetChunk(Fragment) Put DataFile, , Chunk() For I = 1 To Chunks ReDim Buffer(ChunkSize) Chunk() = Rs!Photo.GetChunk(ChunkSize) Put DataFile, , Chunk() Next I Close DataFile FileName = "pictemp" End SubPrivate Sub SaveToDB_Click() If Len(NameWanted) = 0 Then _ NameWanted = InputBox("Enter name for this" _ & " picture", "Animal") Qd(0) = NameWanted Set Rs = Qd.OpenResultset(rdOpenKeyset, _ rdConcurRowver) If Rs Is Nothing Or Rs.Updatable = False Then MsgBox "Can't open or write to result set" Exit Sub End If If Rs.EOF Then Rs.AddNew Rs!PName = NameWanted If Description = "" Then _ Description = InputBox("Describe the picture", _ "Don't care") 'Rs!Description = Description Else Rs.Edit End If DataFile = 1 Open FileName For Binary Access Read As DataFile Fl = LOF(DataFile) ' 文件中数据的长度 If Fl = 0 Then Close DataFile: Exit Sub Chunks = Fl \ ChunkSize Fragment = Fl Mod ChunkSize Rs!Photo.AppendChunk Null ReDim Chunk(Fragment) Get DataFile, , Chunk() Rs!Photo.AppendChunk Chunk() ReDim Chunk(ChunkSize) For I = 1 To Chunks Get DataFile, , Chunk() Rs!Photo.AppendChunk Chunk() Next I Close DataFile Rs.Update End SubPrivate Sub FileName_Change() Picture1.Picture = LoadPicture(FileName) End Sub
本代码演示了如何在网络上不保存文件到硬盘而传送图像。
代码思路是,通过TCP协议握手,将图像保存到一个数组并按照R、G、B三个通道分层,用zlib库压缩到ZipStream数组,对此数组进行Base64编码方便网络传输,然后通过TCP协议实现了网络图像传送,传送到对方之后进行Base64解码和zlib的解压,实现了图像的复原。
主要技术点:
1.自定义协议握手
2.将图像保存到数组(cDIB.MapArray/UnMapArray)
3.利用Zip编码进行图像压缩(cDIB.SaveStream/LoadStream)
4.利用Base64编码实现网络传送(FrmMain.InitBase64/CompBase64/UnCompBase64)
Dim en As rdoEnvironment
Dim Qd As rdoQuery
Dim Cn As rdoConnection
Dim Rs As rdoResultset
Dim SQL As String
Dim DataFile As Integer, Fl As Long, Chunks As Integer
Dim Fragment As Integer, Chunk() As Byte, I As Integer
Const ChunkSize As Integer = 16384Private Sub Form_Load()
Set en = rdoEnvironments(0)
Set Cn = en.OpenConnection(dsname:="", _
Connect:="UID=;PWD=;DATABASE=WorkDB;" _
& ""Driver={SQL Server};SERVER=Betav486", _
prompt:=rdDriverNoPrompt)
Set Qd = Cn.CreateQuery("TestChunk", "Select * from
Chunks Where PName = ?")
End Sub
Private Sub LoadFromFile_Click()
'
' 将文件定位并为该文件设置文件名。
'
With CommonDialog1
.Filter = "Pictures(*.bmp;*.ico)|*.bmp;*.ico"
.ShowOpen
FileName = .FileName
End With
End SubPrivate Sub ReadFromDB_Click()
If Len(NameWanted) = 0 Then _
NameWanted = InputBox("Enter name wanted", "Animal")
Qd(0) = NameWanted
Set Rs = Qd.OpenResultset(rdOpenKeyset,
rdConcurRowver)
If Rs Is Nothing Or Rs.Updatable = False Then
MsgBox "Can't open or write to result set"
Exit Sub
End If
If Rs.EOF Then
MsgBox "Can't find picture by that name"
Exit Sub
End If
Description = Rs!Description
DataFile = 1
Open "pictemp" For Binary Access Write As DataFile
Fl = Rs!Photo.ColumnSize
Chunks = Fl \ ChunkSize
Fragment = Fl Mod ChunkSize
---------------------------------------------------------
ReDim Chunk(Fragment) '这里初始化二进制数组。
--------------------------------------------------------
Chunk() = Rs!Photo.GetChunk(Fragment)
Put DataFile, , Chunk()
For I = 1 To Chunks
ReDim Buffer(ChunkSize)
Chunk() = Rs!Photo.GetChunk(ChunkSize)
Put DataFile, , Chunk()
Next I
Close DataFile
FileName = "pictemp"
End SubPrivate Sub SaveToDB_Click()
If Len(NameWanted) = 0 Then _
NameWanted = InputBox("Enter name for this" _
& " picture", "Animal")
Qd(0) = NameWanted
Set Rs = Qd.OpenResultset(rdOpenKeyset, _
rdConcurRowver)
If Rs Is Nothing Or Rs.Updatable = False Then
MsgBox "Can't open or write to result set"
Exit Sub
End If
If Rs.EOF Then
Rs.AddNew
Rs!PName = NameWanted
If Description = "" Then _
Description = InputBox("Describe the picture", _
"Don't care")
'Rs!Description = Description
Else
Rs.Edit
End If
DataFile = 1
Open FileName For Binary Access Read As DataFile
Fl = LOF(DataFile) ' 文件中数据的长度
If Fl = 0 Then Close DataFile: Exit Sub
Chunks = Fl \ ChunkSize
Fragment = Fl Mod ChunkSize
Rs!Photo.AppendChunk Null
ReDim Chunk(Fragment)
Get DataFile, , Chunk()
Rs!Photo.AppendChunk Chunk()
ReDim Chunk(ChunkSize)
For I = 1 To Chunks
Get DataFile, , Chunk()
Rs!Photo.AppendChunk Chunk()
Next I
Close DataFile
Rs.Update
End SubPrivate Sub FileName_Change()
Picture1.Picture = LoadPicture(FileName)
End Sub
Set ss = CreateObject("ADODB.Stream")' 实例化
ss.Open' 设置成二进制类型(默认是文本型)
ss.Type = adTypeBinary' 将文件读入流,当然你也可以从数据库里面读取数据什么的
ss.LoadFromFile "sample.bmp"' 自行添加对这个流的操作
……' 关闭
ss.Close
Set ss = Nothing