利用Vb保存一幅图到Access数据库

来源:岁月联盟 编辑:zhu 时间:2007-02-01
  在我们做的许多管理系统中,除了保存大量的文字信息以外,有时候也需要保存一定数量的图片。例如:一个人事管理系统,就需要对每个人的照片进行保存,以便可以方便的对每个人的信息进行处理。

    Office中的Access数据库除了保存文本,还可以保存图片,保存图片的数据类型就是"OLE对象":它用来保存 Excel 电子表格、 Word 文档、图形、声音或其他二进制数据。

    我现在用一个例子介绍利用vb保存图片的方法,首先我们要介绍vb中处理二进制数据的语句:Put、Get。

  Put、Get语句语法如下:

  Put [#] filenumber,[recnumber],varname

  Get [#] filenumber,[recnumber],varname

  Filenumber :必需的。任何有效的文件号

  Recnumber :可选的。Variant(Long)。记录号(Random方式的文件)或字节数(Binary方式的文件),指明在此处开始写入

  Varname :必需的。包含要写入磁盘的数据的变量名

    说明:文件中的第一个记录或字节位于位置1,第二个记录或字节位于位置2,依次类推。若省略recnumber,则将上一个Get或Put语句之后的下一个记录或字节写入。所有用于分界的逗号都必须罗列出来。

  

   现在我们来开始建一个工程,功能是保存一个文档,同时可以保存一幅图片。

   首先我们建一个表(表名为photo),字段如下:

  

  

  字段名 类型 标题

  class 类别 文档的分类

  photo OLE对象 保存图片文件

  photo_ext 文本 图片的扩展名

  inputtime 日期/时间 文档输入的时间

  modifytime 日期/时间 文档的修改时间

  

  subject 文本 文本

  

  

  现在我们就可以创建finput窗口文件来保存图片。

  首先我们要连接我们的数据库,代码如下:

  Dim cnstr As String

  cnstr = "Provider=Microsoft.Jet.OLEDB.4.0;Persist Security Info=False;" _

  & "Data Source=" & App.Path & "/realize.mdb;Jet OLEDB:database "

  cn.Open cnstr

  cn.CursorLocation = adUseClient

  这段代码可以放在form_load事件中,当做一个多窗口的系统时,最好放到一个模块文件中,这样在其它窗口中都可以调用这个cn连接。

  下面是具体的窗口代码:

   VERSION 5.00

   Object= "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "comdlg32.ocx"

   Object= "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "richtx32.ocx"

   Begin VB.Form finput

   BorderStyle = 0 'None

   Caption = "文档输入"

   ClientHeight = 6240

   ClientLeft = 0

   ClientTop = 0

   ClientWidth = 8955

   ControlBox = 0 'False

   LinkTopic = "Form1"

   MDIChild = -1 'True

   ScaleHeight = 6240

   ScaleWidth = 8955

   ShowInTaskbar = 0 'False

   Begin MSComDlg.CommonDialog CommonDialog1

   Left = 8040

   Top = 3840

   _ExtentX = 847

   _ExtentY = 847

   _Version = 393216

   End

   Begin VB.ComboBox Combo1

   Height = 300

   Left = 7080

   TabIndex = 10

   Top = 480

   Width = 1335

  End

   Begin VB.CommandButton Command3

   Caption = "关闭"

   Height = 375

   Left = 5280

   TabIndex = 8

   Top = 5640

   Width = 1095

  End

   Begin VB.CommandButton Command2

   Caption = "保存"

   Height = 375

   Left = 2520

   TabIndex = 7

   Top = 5640

   Width = 1095

  End

   Begin VB.CommandButton Command1

   Caption = "浏览"

   Height = 255

   Left = 8040

   TabIndex = 6

   Top = 4800

   Width = 735

  End

   Begin VB.TextBox Text2

   Height = 375

   Left = 1200

   TabIndex = 5

   Top = 4800

   Width = 6375

  End

   Begin RichTextLib.RichTextBox RichTextBox1

   Height = 3615

   Left = 1200

   TabIndex = 3

   Top = 960

   Width = 6375

   _ExtentX = 11245

   _ExtentY = 6376

   _Version = 393217

   Enabled = -1 'True

   TextRTF = $"finput.frx":0000

  End

   Begin VB.TextBox Text1

   Height = 375

   Left = 1200

   TabIndex = 2

   Top = 443

   Width = 4695

  End

   Begin VB.Label Label4

   Caption = "类别"

   Height = 255

   Left = 6240

   TabIndex = 9

   Top = 480

   Width = 615

  End

   Begin VB.Label Label3

   Caption = "图片"

   Height = 255

   Left = 480

   TabIndex = 4

   Top = 4800

   Width = 495

  End

   Begin VB.Label Label2

   Caption = "内容"

   Height = 255

   Left = 480

   TabIndex = 1

   Top = 960

   Width = 495

  End

   Begin VB.Label Label1

   Caption = "标题"

   Height = 255

   Left = 480

   TabIndex = 0

    Top = 503

   Width = 495

  End

  End

   Attribute VB_Name = "finput"

   Attribute VB_GlobalNameSpace = False

   Attribute VB_Creatable = False

   Attribute VB_PredeclaredId = True

   Attribute VB_Exposed = False

   Option Explicit

  

   Private Sub Command1_Click()

   CommonDialog1.DefaultExt = App.Path

   CommonDialog1.Filter = "Pictures (*.bmp;*.jpg;*.gif) *.bmp;*.jpg;*.gif" '注意要加引号

   CommonDialog1.ShowOpen

   Text2.Text = CommonDialog1.FileName

  End Sub

  

   '保存文档的标题,和文档的内容,以及相应的图片

   Private Sub Command2_Click()

   '判断是否所写的文档是否已经存在数据库了,如果没有,则保存,否则

   '不能保存(利用一个"临时rs"查询标题)

   Dim subject, sql As String

   Dim temp_photo As Stream

   Dim rs As New ADODB.Recordset

   Dim rs1 As New ADODB.Recordset '定义rs1得到类别的id

   Dim class_id As Integer '定义得到类别的ID号

   subject = Trim(Text1.Text) '获得标题

   sql = "select * from paper where subject='" + subject + "'"

   '开始查询

   rs.Open sql, cn, adOpenDynamic, adLockPessimistic

   '判断标题是否存在

  

   If rs.EOF Then '文档不存在,开始保存

   Dim tempdate As Date '临时时间变量

   tempdate = Date

  

  

   rs.AddNew

  

   '得到类别的ID

   sql = "select cl_number,class from class where class='" + Combo1.Text + "'"

   rs1.Open sql, cn, adOpenDynamic, adLockPessimistic

   rs("class") = rs1("cl_number")

   rs1.Close '关闭rs1

  

   rs("subject") = subject

   rs("content") = RichTextBox1.Text

   If Trim(Text2.Text) <> "" Then '假如有图片,开始得到图片文件

   Dim image_data() As Byte '定义图片保存的变量

  

   Open Trim(Text2.Text) For Binary As #1

   ReDim image_data(LOF(1) - 1)

   Get #1, , image_data()

   rs("photo").AppendChunk image_data()

   End If

  

   rs("inputtime") = tempdate

   rs("modifytime") = tempdate

   rs.Update '可能出现保存不成功的现象,所以要考虑可能会出现错误

   MsgBox ("保存成功!") '保存成功

   Text1.Text = ""

   RichTextBox1.Text = ""

   Text2.Text = "" '此处清空选择图片的框

  

   Else '存在,不能保存,显示错误信息

   MsgBox ("文档已经存在,不能保存,请修改!")

  End If

  

   rs.Close '关闭结果集

  End Sub

  

   Private Sub Command3_Click()

   Unload Me

   End Sub

  

   Private Sub Form_Load()

   Me.Left = 0

   Me.Top = 0

   fmain.Width = Me.Width + 340

   fmain.Height = Me.Height + 1550

   '显示文档的类别

   Dim rs As New ADODB.Recordset

   Dim sql As String

   sql = "select * from class"

   rs.Open sql, cn, 1, 1

   Do While Not rs.EOF '类别不空,则添加进去,对应类别的number为索引

   Combo1.AddItem rs("class")

   rs.MoveNext

  Loop

   If rs.RecordCount <> 0 Then '只有查询结果集不为空时,才能设定显示第一项,利用纪录总数不为0判定

   Combo1.ListIndex = 0 '不能用not rs.eof判定,因为现在cursor已经到了最后

  End If

   rs.Close

  End Sub

  当然,在上面这段代码中,还用到了另一个表(表名为class),字段如下:

  

  

  

  字段名 类型 意义

  class 文本 文档类别的名称

  cl_number 数字 类别的编号

  

  上面的代码可以较好的保存我们的文档和图片,我们还需要显示我们的图片和文档,现在我们还要显示我们的图片,我做了一个显示窗口(fshow),现在我假设数据库中有 一条记录,subject为"ipx协议简介",里面有一个图片(ipx体系结构),窗口代码如下:

  VERSION 5.00

   Object = "{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.0#0"; "mscomctl.ocx"

   Object = "{3B7C8863-D78F-101B-B9B5-04021C009402}#1.2#0"; "richtx32.ocx"

   Begin VB.Form fshow

   BorderStyle = 0 'None

   Caption = "显示图片"

   ClientHeight = 7125

   ClientLeft = 0

   ClientTop = 0

   ClientWidth = 10275

   LinkTopic = "Form1"

   MDIChild = -1 'True

   ScaleHeight = 7125

   ScaleWidth = 10275

   ShowInTaskbar = 0 'False

   Begin VB.Frame Frame2

   Height = 6615

   Left = 2880

   TabIndex = 1

   Top = 240

   Width = 7335

   Begin VB.CommandButton Command1

   Caption = "关闭"

   Height = 375

   Left = 5880

   TabIndex = 5

   Top = 5880

   Width = 1215

  End

   Begin RichTextLib.RichTextBox RichTextBox1

   Height = 4095

   Left = 120

   TabIndex = 4

   Top = 1200

   Width = 6975

   _ExtentX = 12303

   _ExtentY = 7223

   _Version = 393217

   TextRTF = $"fshow.frx":0000

  End

   Begin VB.Image Image1

   Height = 855

   Left = 120

   Stretch = -1 'True

   Top = 5640

   Width = 1095

  End

   Begin VB.Line Line4

   X1 = 5520

   X2 = 5520

   Y1 = 5520

   Y2 = 6600

  End

   Begin VB.Line Line3

   X1 = 0

   X2 = 7320

   Y1 = 5520 

   Y2 = 5520

  End

   Begin VB.Line Line2

   X1 = 0

   X2 = 7320

   Y1 = 960

   Y2 = 960

  End

   Begin VB.Label Label1

   BackColor = &H80000009&

   Height = 615

   Left = 120

   TabIndex = 3

   Top = 240

   Width = 7095

  End

  End

   Begin VB.Frame Frame1

   Height = 6735

   Left = 120

   TabIndex = 0

   Top = 240

   Width = 2535

   Begin MSComctlLib.TreeView TreeView1

   Height = 6375

   Left = 120

   TabIndex = 2

   Top = 240

   Width = 2295

   _ExtentX = 4048

   _ExtentY = 11245

   _Version = 393217

   PathSeparator = ""

   Style = 7

   Appearance = 1

  End

  End

   Begin VB.Line Line1

   BorderColor = &H80000001&

   X1 = 2760

   X2 = 2760

   Y1 = 120

   Y2 = 6960

  End

  End

   Attribute VB_Name = "fshow"

   Attribute VB_GlobalNameSpace = False

   Attribute VB_Creatable = False

   Attribute VB_PredeclaredId = True

   Attribute VB_Exposed = False

   Option Explicit

  

  Private Sub Command1_Click()

   Unload Me

  End Sub

  

   Private Sub Form_Load()

   Dim temptop, templeft As Long

   Me.Left = 0

   Me.Top = 0

   fmain.Width = Me.Width + 340

   fmain.Height = Me.Height + 1550

   fmain.Top = (Screen.Height - fmain.Height) / 2

   fmain.Left = (Screen.Width - fmain.Width) / 2

  

  '显示结果

   Dim rs As New ADODB.Recordset

   Dim image_filename As String

   Dim temp_image() As Byte

   Dim sql As String

   sql = "select * from paper where subject=' ipx协议简介'"

   rs.Open sql, cn, adOpenDynamic, adLockReadOnly

   Label1.Caption = rs("inputtime")

   temp_image() = rs("photo")

   image_filename = App.Path + "/temp." + rs("photo_ext")

   rs.Close

   '建立临时文件

   Open image_filename For Binary As #1

   Put #1, , temp_image()

   Close #1

   Image1.Picture = LoadPicture(image_filename)

   '删除临时文件

   Kill image_filename

  End Sub

    上面代码只能显示一条记录,而且需要先赋条件,显示图片用的是先建一个临时文件,然后把二进制数据读到这个文件里,同时要赋给正确的扩展名,然后可以显示图片,注意,要及时删除临时文件。

  总结:这种方法只是保存图片的其中一种,还有其它保存到数据库的方法,希望大家不断的交流其它的保存图片的方法。