Hi guy,

I currently having problem saving my drawing into the sql database.

Can I get some help here pls.

my current codes:

Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Drawing
Imports System.Drawing.Drawing2D

Public Class Page_2
    ' for GCS TABLE
    Private value_GCS As Integer = 0
    Dim value_Eyes As String = ""
    .
    .
    .
    Dim value_UrinaryCatheter As String = ""

    ' for freehand drawing
    Dim mousePath As New System.Drawing.Drawing2D.GraphicsPath() 'declare a new Graphic path to follow the mouse movement
    Dim myAlpha As Integer = 100 ' declare a Alpha variable
    Dim myUserColor As New Color() 'this is a color the user selects
    Dim myPenWidth As Single = 5 'set pen width variable

    Private Sub Page_2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        lbl_Total.Text = CStr(value_GCS)

    End Sub

    Private Sub cbEyes4_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cbEyes4.MouseClick

        cbEyes1.Checked = False
        .
        .
        .
        update_GCSTotal()
        value_Eyes = "4"

    End Sub

.
.
.


    Private Sub cbVerbal4_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cbVerbal4.MouseClick

        cbVerbal1.Checked = False
        .
        .
        .
        cbVerbal5.Checked = False
        update_GCSTotal()
        value_Verbal = "4"

Ebd Sub

    Sub update_GCSTotal()

        value_GCS = 0

        If Me.cbEyes1.Checked Then
            value_GCS += CInt(Me.cbEyes1.Text)
        End If

        .
        .
        .
        .
        .
        If Me.cbMotor5.Checked Then
            value_GCS += CInt(Me.cbMotor5.Text)
        End If

        If Me.cbMotor6.Checked Then
            value_GCS += CInt(Me.cbMotor6.Text)
        End If

        lbl_Total.Text = CStr(value_GCS)

    End Sub


    Private Sub cbIntubationOral_MouseClick(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cbIntubationOral.MouseClick

        cbIntubationOral.Checked = True
        cbIntubationNasal.Checked = False
        value_Intubation = "Oral"

    End Sub

    Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click

        Dim connAdd As New SqlConnection _
        ("Data Source=152.226.152.99\SQLEXPRESS,1433;" + "Initial Catalog=TAR;" + "User ID=Remote;" + "Password=123;")
        'Client's IP: 152.226.152.76    Host's PC: 152.226.152.99

     .
     .
     .

        Dim mySQL As String

        Try
            connAdd.Open()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error Open", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        mySQL = "insert into gcs (eyesOpen, verbal, motor, totalGcs) values ('" & Trim(value_Eyes) & "','" & Trim(value_Verbal) & "','" & Trim(value_Motor) & "','" & Trim(lbl_Total.Text) & "' ) "

        Dim cmdAdd As New SqlCommand(mySQL, connAdd)

        Try
            cmdAdd.ExecuteNonQuery()
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error Query", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

        Dim Response As New Page_3()
        Page_3.Show()
        Me.Hide()

    End Sub

    Private Sub btnBack_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBack.Click

        Dim Response As New Page_1()
        Page_1.Show()
        Me.Hide()

    End Sub

    Private Sub pbBody_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseDown

        If e.Button = MouseButtons.Left Then ' draw a filled circle if left mouse is down  

            mousePath.StartFigure()    ' The L mouse is down so we need to start a new line in mousePath

        End If

    End Sub

    Private Sub pbBody_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseMove

        If e.Button = MouseButtons.Left Then ' draw a filled circle if left mouse is down  

            Try
                mousePath.AddLine(e.X, e.Y, e.X, e.Y)    'Add mouse coordiantes to mousePath

            Catch
                MsgBox("No way, Hose!")
            End Try

        End If

        pbBody.Invalidate() 'Repaint the PictureBox using the PictureBox1 Paint event

    End Sub

    Private Sub pbBody_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pbBody.Paint
        ' Here is where we do the actual painting

        Try ' error trapping

            myUserColor = (System.Drawing.Color.Black) 'You can remove this line and add a user selected color to
            'change the value of myUserColor

            myAlpha = 200  ' This will give the color a Alpha effect, you can set this to 255 if you want a full color

            '*********************** NOTE  ***********************************************
            'The line below set the pen up with the ability to add user selected Alpha, Color and Penwidth
            ' A simpler, but less flexible solution would be to replace the line with the following code:
            'Dim CurrentPen = New Pen(System.Drawing.Color.Black, myPenWidth)
            '************  End Note  ***************************

            Dim CurrentPen As New Pen(Color.FromArgb(myAlpha, myUserColor), myPenWidth) 'Set up the pen

            e.Graphics.DrawPath(CurrentPen, mousePath)  'draw the path! :)

        Catch
            ' MsgBox("Not happening!")
        End Try
    End Sub

End Class

how do I do my saving and what is the datatype i used in my sql database for the images?

Thks

I suggest using BLOB data type.

I don't have BLOB datatype in my sql database choices. the available choices are bigInt, binary, bit, char, dateTime, decimal(18,0), float, image, int, money, nchar(10), ntext, numeric(18,0), nvarchar(50), nvarchar(MAX), real, smalldatetime, smallInt, smallMoney, sql_variant, text, timestamp, tinyInt, uniqueIdentifier, varBinary(50), varBinary(MAX), varchar(50), varchar(MAX), xml. OR u mean

Dim image As BLOB = ""

Tem, OP has Microsoft Sql Server database. OP cannot find a name of installed database.

DAWNIE,
You are using MS - SQL server and you have to use Image field type to store file content.

Image Field represents array of bytes.

To write file content, Use parameterized query.

adatapost > OP cannot find a name of installed database.
The connection string seems ok to me :-/

SQL server and you have to use Image field type to store file content

Sorry, my mistake. It's called Image in SQL Server, not BLOB :)

No sir, it's OP's mistake. He/She mentioned mysql in his/her post.

To write file content, Use parameterized query.

adatapost > Sorry, I don't understand the meaning of above statement.

it's OP's mistake. He/She mentioned mysql in his/her post

adatapost > Do you mean my mistake? Sry, whr did I posted wrong or something wrong with my codes?

convert image to an array of bytes first. See Save binary data to SQL Server with VB.NET how to save byte array to SQL Server.

I assume you're using picture box control. See Convert image to byte array and vice versa how to get a byte array from an image.

Teme64 > Does this website still can help me on saving my drew image to MS - SQL server?

Thks =)

Teme64 > Does this website still can help me on saving my drew image to MS - SQL server?

Actually I'm not 100% sure. I haven't used the snippet in that kind of scenario, but I suggest you copy/paste the code(s) and try it out.

If I remember right, you were using picture box control and you drew user selections on it. And now you want to save it all to database, right?

Here's the picture box to byte array procedure

''' <summary>
''' Convert an image to array of bytes
''' </summary>
''' <param name="NewImage">Image to be converted</param>
''' <param name="ByteArr">Returns bytes</param>
''' <remarks></remarks>
Public Sub Image2Byte(ByRef NewImage As Image, ByRef ByteArr() As Byte)
  '
  Dim ImageStream As System.IO.MemoryStream

  Try
    ReDim ByteArr(0)
    If NewImage IsNot Nothing Then
      ImageStream = New System.IO.MemoryStream
      NewImage.Save(ImageStream, System.Drawing.Imaging.ImageFormat.Jpeg)
      ReDim ByteArr(CInt(ImageStream.Length - 1))
      ImageStream.Position = 0
      ImageStream.Read(ByteArr, 0, CInt(ImageStream.Length))
    End If
  Catch ex As Exception

  End Try

End Sub

You can test it with

Dim ImageByteArr() As Byte = {0}
Image2Byte(PictureBox1.Image, ImageByteArr)

and after that, check with the second picture box

Byte2Image(PictureBox2.Image, ImageByteArr)

that you do get the same image (Byte2Image code not copied in here, see the link in my first post).

If you do get the image converted correctly back and forth to/from a byte array, use that saving binary data to SQL Server code (link to code was in my first post). And the correct data type with SQL Server is Image type like adatapost corrected. It's called BLOB in some other DB.

However, if you don't manage to do image and byte array conversions, post your code and possible error messages. I'll have to then test it myself why it wouldn't work.

A sample demonstrate : create, draw, and save an image.

Public Class Form2
    'Graphics & Bitmap object variables
    Dim grp As Graphics
    Dim bmp As Bitmap

   'Save an image to disk file or database.
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
       'Memory stream
        Dim ms As New System.IO.MemoryStream

       'Write an image data into memory stream
        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png)

 'To save an image into disk file       
 'bmp.Save("p1.png", System.Drawing.Imaging.ImageFormat.Png)
       
        'Byte array
        Dim b() As Byte = ms.ToArray

        Dim cn As New System.Data.SqlClient.SqlConnection("CnStr")
      
        'Parameterized Query
        Dim cmd As New SqlClient.SqlCommand("insert into mytable (myid,myimage) values (@p1,@p2)", cn)
         
        'Create/add parameters
        '@p1 - name of parameter, datatype,size,"columnname"
        cmd.Parameters.Add("@p1", SqlDbType.Int, 4, "myid")
        cmd.Parameters.Add("@p2", SqlDbType.Image, b.Length, "myimage")
       
        'Assign value to the parameters
        cmd.Parameters("@p1").Value = 1
        cmd.Parameters("@p2").Value = b

        'Execute command
        cn.Open()
        cmd.ExecuteNonQuery()
        cn.Close()
    End Sub


    Private Sub Form2_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles Me.Paint
        'Create an image (bitmap) object of size(200,200)
        
        If IsNothing(bmp) Then
            bmp = New Bitmap(200, 200)
        End If
        
        grp = Graphics.FromImage(bmp)
        grp.DrawArc(Pens.Aqua, 10, 10, 200, 200, 100, 100)
        grp.DrawImage(bmp, 0, 0)
        e.Graphics.DrawImage(bmp, 0, 0)
    End Sub
End Class
'Write an image data into memory stream        
        pbBody.CreateGraphics.Save(ms, System.Drawing.Imaging.ImageFormat.Png)

I have my default picture so do I edit my code this way? but there is this prompt "Too many arguments to 'Public Function Save() As System.Drawing.Drawing2D.GraphicsState". so how do i solve this issue?

'Parameterized Query        
        Dim cmd As New SqlClient.SqlCommand("insert into image (myid,myimage) values ('" & Trim(lblId.text) & "','" & Trim(?) & "')", cn)

How do I get the p2? isit the picturebox's name?

If you use adatapost's code:

I have my default picture so do I edit my code this way? but there is this prompt "Too many arguments to 'Public Function Save() As System.Drawing.Drawing2D.GraphicsState". so how do i solve this issue?

use the Image property of the picture box

'Write an image data into memory stream        
pbBody.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png)

How do I get the p2? isit the picturebox's name?

No, it's the image from the picture box converted to an array of bytes. You can't use the following SQL syntax with Image data type

Dim cmd As New SqlClient.SqlCommand("insert into image (myid,myimage) values ('" & Trim(lblId.text) & "','" & Trim(?) & "')", cn)

Instead check, how adatapost used the parameters in the query (lines 8 - 32 from his post)

'Memory stream
Dim ms As New System.IO.MemoryStream

'Write an image data into memory stream
pbBody.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png)

'To save an image into disk file       
'pbBody.Image.Save("p1.png", System.Drawing.Imaging.ImageFormat.Png)
       
'Byte array
Dim b() As Byte = ms.ToArray
'Parameterized Query
Dim cmd As New SqlClient.SqlCommand("insert into mytable (myid,myimage) values (@p1,@p2)", cn)
         
'Create/add parameters
'@p1 - name of parameter, datatype,size,"columnname"
cmd.Parameters.Add("@p1", SqlDbType.Int, 4, "myid")
cmd.Parameters.Add("@p2", SqlDbType.Image, b.Length, "myimage")
       
'Assign value to the parameters
cmd.Parameters("@p1").Value = CInt(lblId.text) ' ASSUMING YOU'RE USING INT TYPE AS ID
cmd.Parameters("@p2").Value = b ' THIS IS BYTE ARRAY CONTAINING THE IMAGE. SEE FEW LINES ABOVE

If you looked my code, you'd seen that I used a parameter in the query too. And AFAIK that's the only way to do it.

commented: Well explained. +6

I have this prompt when I try to do my saving after drawing circle. Format of the initialization string does not conform to specification starting at index 0.


Dim cn As New System.Data.SqlClient.SqlConnection("CnStr")

Above is the line that is being highlighted for error.

Did i did the code correctly this time? how do i declare varchar's object expression?

Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click

'Memory stream        
        Dim ms As New System.IO.MemoryStream
        'Write an image data into memory stream        
        pbBody.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Png)

        'Byte array        
        Dim b() As Byte = ms.ToArray
        Dim cn As New System.Data.SqlClient.SqlConnection("CnStr")
        'Parameterized Query        
        Dim cmd As New SqlClient.SqlCommand("insert into image (patientIC,picture) values (@p1,@p2)", cn)
        'Create/add parameters        
        '@p1 - name of parameter, datatype,size,"columnname"       
        cmd.Parameters.Add("@p1", SqlDbType.VarChar, 50, "patientIC")
        cmd.Parameters.Add("@p2", SqlDbType.Image, b.Length, "picture")
        'Assign value to the parameters        
        cmd.Parameters("@p1").Value = __?__ (lblId.Text)
        cmd.Parameters("@p2").Value = b
        'Execute command        
        cn.Open()
        cmd.ExecuteNonQuery()

    End Sub

Sorry if i'm stil as blur.

and my code for drawing multi circle..

Private Sub pbBody_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseDown

        'Initialise Starting Points Of Shape, Once Mouse Button Is Pressed Down
        sStartX = e.X
        sStartY = e.Y

    End Sub

    Private Sub pbBody_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseUp

        'Initialise Ending Points Of Shape, Once Mouse Button Is Released
        sEndX = e.X
        sEndY = e.Y

        'Draw The Circle With The Current Starting, And Ending Values.
        'We must subtract the Starting values from the Ending values,
        'to make sure the shape's Starting and ending values are
        'precisely those where you started drawing, and where you
        'ended drawing.
        pbBody.CreateGraphics.DrawEllipse(pPen, sStartX, sStartY, _
                            sEndX - sStartX, sEndY - sStartY)

    End Sub

Y does my circle's line alway gone missing when i scroll up n down my image?

Dim cn As New System.Data.SqlClient.SqlConnection("CnStr")

Maybe you shouldn't have quotes around CnStr (assuming it's a variable). Your code should be similar to

Dim CnStr As String
CnStr = "Data Source=MyMachineName\SQLEXPRESS; INITIAL CATALOG=MyDatabase; User ID=XXX; Password=XXX;"
' or CnStr = "Data Source=MyMachineName; INITIAL CATALOG=MyDatabase; User ID=XXX; Password=XXX;"
Dim cn As New System.Data.SqlClient.SqlConnection(CnStr)

See Connection strings for SQL Server 2005 for the correct format of the connection string.

cmd.Parameters("@p1").Value = __?__ (lblId.Text)

should be

cmd.Parameters("@p1").Value = lblId.Text

assuming that label lblId contains a valid PatientID.

Y does my circle's line alway gone missing when i scroll up n down my image?

Because picture boxes Paint event redraws the image (without your drawings).

I found two solution with googling. I didn't either test or try them so you'll have to check them yourself. First solution may be easier to modify for your needs. The latter one is for Pocket PC but should be portable to WinForms application:
I'm having a problem with drawing on picturebox in vb.net programing
and PictureBox Drawing VB.NET, here's the correct link to sample code: Scribbler Technology Sample

i hav done the saving part but it shown in table patient's ID and binary data. m i on the right track? the image is save as binary data?

DAWNIE,
You are right. This technique insert content of any type (image, doc, sheet, program, html etc) of file into a table.

okok. thanks adatapost & Teme64. I can manage to save the file but hav yet to try retrieving it back from database. =)

Thanks lots

I still having problem for the re-draw part. i have added the codes below to my application:

Private Sub pbBody_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pbBody.Paint

        'Draw the Final rectangle, as a repaint was issued
        e.Graphics.DrawEllipse(pPen, sStartX, sStartY, _
                            sEndX - sStartX, sEndY - sStartY)

    End Sub    Private Sub pbBody_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pbBody.Paint

        'Draw the Final rectangle, as a repaint was issued
        e.Graphics.DrawEllipse(pPen, sStartX, sStartY, _
                            sEndX - sStartX, sEndY - sStartY)

    End Sub

The above codes only save what is being drew the latest. which mean only the new circle that is being draw wont disappear when i scroll up & down whereby the remainin circle will disappear.

Teme64 > I had try the 2 website that u gave me but i don't really get the way on how they do it.

Here's the repainting code. All the user drawings are saved on the arrays. On the picture box's paint event all the saved user drawings are repainted from the arrays

' "Drawing" arrays
Private sStartX() As Integer
Private sStartY() As Integer
Private sEndX() As Integer
Private sEndY() As Integer
' Remove New and (Color.White), they're just for debugging
Private pPen As New System.Drawing.Pen(Color.White) ' DECLARE THIS AS AN ARRAY IF THE PEN CAN BE CHANGED
' Counter for the arrays, -1 = nothing drawed yet
Private m_DrawIndex As Integer = -1

Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown

  'Initialise Starting Points Of Shape, Once Mouse Button Is Pressed Down
  ' Start a new drawing: increase the counter and redim the arrays
  m_DrawIndex += 1
  ReDim Preserve sStartX(m_DrawIndex)
  ReDim Preserve sStartY(m_DrawIndex)
  ReDim Preserve sEndX(m_DrawIndex)
  ReDim Preserve sEndY(m_DrawIndex)
  'ReDim Preserve pPen(m_DrawIndex) ' Only if pPen is an array too
  '
  sStartX(m_DrawIndex) = e.X
  sStartY(m_DrawIndex) = e.Y

End Sub

Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

  'Initialise Ending Points Of Shape, Once Mouse Button Is Released
  sEndX(m_DrawIndex) = e.X
  sEndY(m_DrawIndex) = e.Y

  'Draw The Circle With The Current Starting, And Ending Values.
  'We must subtract the Starting values from the Ending values,
  'to make sure the shape's Starting and ending values are
  'precisely those where you started drawing, and where you
  'ended drawing.
  PictureBox1.CreateGraphics.DrawEllipse(pPen, sStartX(m_DrawIndex), sStartY(m_DrawIndex), _
                      sEndX(m_DrawIndex) - sStartX(m_DrawIndex), sEndY(m_DrawIndex) - sStartY(m_DrawIndex))

End Sub

Private Sub PictureBox1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles PictureBox1.Paint

  'Draw the Final rectangle, as a repaint was issued

  ' Redraw user drawings from the array
  Dim i As Integer

  For i = 0 To m_DrawIndex
    e.Graphics.DrawEllipse(pPen, sStartX(i), sStartY(i), _
                            sEndX(i) - sStartX(i), sEndY(i) - sStartY(i))
  Next i

End Sub

With this code you could also implement very easily "undo" option simply by decreasing array pointer (i.e. m_DrawIndex variable) and redimming arrays with the new array pointer value.

HTH

P.s.

I had try the 2 website that u gave me but i don't really get the way on how they do it.

A short and quick answer: The first one is the code which converts image (i.e. Picturebox.Image property) to an array of bytes. This array of bytes can be saved to SQL Server's field of type Image. The latter code does that. There's also subroutines to retrieve the image back from the SQL Server to picture box control. Except that the latter link doesn't provide code for that, I just noticed ;) I'll try to write and post that code ASAP (I'm on holiday). Saving the Image type requires parametrized insert statement, maybe that's a bit confusing? And finally, adatapost's code does the same thing i.e. shows how to use parametrized queries.

commented: I appreciate your post +7

Here's a complete (example) code for saving a picture box control's image to SQL Server and loading it back

Option Strict On
Option Explicit On

Imports System.Drawing.Imaging  ' Image related methods etc.
Imports System.IO               ' MemoryStream
Imports System.Data.SqlClient   ' SQl Server related classes

Public Class Form1

  ' Class global variable
  Private m_CnStr As String ' Connection string to DB

  ' Table structure:
  ' ImageTable:
  '
  ' ImageID	  varchar(50)
  ' BlobField image

  ''' <summary>
  ''' Convert a byte array to an Image
  ''' </summary>
  ''' <param name="NewImage">Image to be returned</param>
  ''' <param name="ByteArr">Contains bytes to be converted</param>
  ''' <remarks></remarks>
  Public Sub Byte2Image(ByRef NewImage As Image, ByVal ByteArr() As Byte)
    '
    Dim ImageStream As MemoryStream

    Try
      If ByteArr.GetUpperBound(0) > 0 Then
        ImageStream = New MemoryStream(ByteArr)
        NewImage = Image.FromStream(ImageStream)
      Else
        NewImage = Nothing
      End If
    Catch ex As Exception
      NewImage = Nothing
    End Try

  End Sub

  ''' <summary>
  ''' Convert an image to array of bytes
  ''' </summary>
  ''' <param name="NewImage">Image to be converted</param>
  ''' <param name="ByteArr">Returns bytes</param>
  ''' <remarks></remarks>
  Public Sub Image2Byte(ByRef NewImage As Image, ByRef ByteArr() As Byte)
    '
    Dim ImageStream As MemoryStream

    Try
      ReDim ByteArr(0)
      If NewImage IsNot Nothing Then
        ImageStream = New MemoryStream
        NewImage.Save(ImageStream, ImageFormat.Jpeg)
        ReDim ByteArr(CInt(ImageStream.Length - 1))
        ImageStream.Position = 0
        ImageStream.Read(ByteArr, 0, CInt(ImageStream.Length))
      End If
    Catch ex As Exception

    End Try

  End Sub

  ''' <summary>
  ''' Save a byte array to database
  ''' </summary>
  ''' <param name="ByteArr">Contains bytes to be saved</param>
  ''' <param name="ImageID">ID for the image</param>
  ''' <remarks></remarks>
  Public Sub SaveByteArray(ByVal ByteArr() As Byte, ByVal ImageID As String)
    '
    Dim strSQL As String
    Dim oConn As SqlConnection
    Dim oCmd As SqlCommand
    Dim oVarCharParam As SqlParameter
    Dim oBLOBParam As SqlParameter

    Try
      ' Create and open connection object
      oConn = New SqlConnection(m_CnStr)
      oConn.Open()
      ' Insert statement
      ' Notice that @BLOBValue is a placeholder for the actual data
      strSQL = "INSERT INTO ImageTable (ImageID, BlobField) VALUES (@IDValue, @BLOBValue)"
      ' Create a command object
      oCmd = oConn.CreateCommand()
      ' Set SQL statement
      oCmd.CommandText = strSQL
      ' Create a command parameter
      oVarCharParam = New SqlParameter("@IDValue", SqlDbType.VarChar, _
         50, ParameterDirection.Input.ToString)
      ' Set the actual data
      oVarCharParam.Value = ImageID
      ' Add this parameter to the command
      oCmd.Parameters.Add(oVarCharParam)
      ' Create a command parameter
      oBLOBParam = New SqlParameter("@BLOBValue", SqlDbType.Binary, _
        ByteArr.Length, ParameterDirection.Input.ToString)
      ' Finally, set the actual data
      oBLOBParam.Value = ByteArr
      ' Add this parameter to the command
      oCmd.Parameters.Add(oBLOBParam)
      ' Execute SQL statement
      oCmd.ExecuteNonQuery()
      ' Close the connection
      oConn.Close()
    Catch ex As Exception

    End Try

  End Sub

  ''' <summary>
  ''' Load a byte array from database
  ''' </summary>
  ''' <param name="ByteArr">Contains bytes from the database</param>
  ''' <param name="ImageID">ID for the image</param>
  ''' <remarks></remarks>
  Public Sub LoadByteArray(ByRef ByteArr() As Byte, ByVal ImageID As String)
    '
    Dim strSQL As String
    Dim oConn As SqlConnection
    Dim oCmd As SqlCommand
    Dim ValueFromDB As Object ' ExecuteScalar method returns an object

    Try
      ' Create and open connection object
      oConn = New SqlConnection(m_CnStr)
      oConn.Open()
      ' Select statement
      strSQL = "SELECT BlobField FROM ImageTable WHERE ImageID='" & ImageID & "'"
      ' Create a command object
      oCmd = oConn.CreateCommand()
      ' Set SQL statement
      oCmd.CommandText = strSQL
      ' Execute SQL statement
      ValueFromDB = oCmd.ExecuteScalar()
      ' Close the connection
      oConn.Close()
      ' Convert returned object to an array of bytes
      If ValueFromDB IsNot DBNull.Value Then
        ByteArr = CType(ValueFromDB, Byte())
      End If
    Catch ex As Exception

    End Try

  End Sub

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    ' DEBUG: Load an (initial) image to picture box control
    PictureBox1.Image = Image.FromFile("D:\image.jpg")

    ' Initialize DB connection, REPLACE VALUES!
    ' m_CnStr = "Data Source=database name; INITIAL CATALOG=table name; User ID=user name; Password=user password;"

    m_CnStr = "Data Source=xxx\SQLEXPRESS; INITIAL CATALOG=xxx; User ID=xxx; Password=xxx;"

    ' DEBUG: Test image ID
    TextBox1.Text = "patient_image_001"

  End Sub

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    ' Saves the image from the picture box control to SQL Server
    Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
    Dim PatientID As String ' ID for the image

    ' Get ID from a text box control and remove spaces
    PatientID = TextBox1.Text.Trim
    ' Convert image to an array of bytes
    Image2Byte(PictureBox1.Image, ImageByteArr)
    ' Save an array of bytes to SQL Server's field of type Image
    SaveByteArray(ImageByteArr, PatientID)

  End Sub

  Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
    ' Loads the image to the picture box control from SQL Server
    Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
    Dim PatientID As String ' ID for the image

    ' Get ID from a text box control and remove spaces
    PatientID = TextBox1.Text.Trim
    ' Load an array of bytes from SQL Server's field of type Image
    LoadByteArray(ImageByteArr, PatientID)
    ' Convert an array of bytes to image
    Byte2Image(PictureBox1.Image, ImageByteArr)

  End Sub

  Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    ' DEBUG: Clear the image
    PictureBox1.Image = Nothing

  End Sub

End Class

Create a new project (or just a form). Drop three button controls, one text box control and one picture box control to the form. Button1 saves the image, Button2 loads the image and Button3 clears the image (just for testing). I tried to comment the code so it should be understandable. The code is missing error handling and some "sanity checks" for the input to keep it short. And of course, you have to create a table for the data and replace connection string, table name and field names in the code.

HTH

thanks alot for the effort for the example coding. before your codes above, i was using:

Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Drawing.Imaging

Public Class Page_2

    'Declare Starting Points For Drawn Objects
    Private sStartX() As Integer
    Private sStartY() As Integer

    'Declare Ending points For Drawn Objects
    Private sEndX() As Integer
    Private sEndY() As Integer

    'Create And Initialise Pens To Draw The Particular Outline Shapes With.  Color : Black, Width : 1
    Dim pPen As New Pen(Color.Black, 1)

    ' Counter for the arrays, -1 = nothing drawed yet
    Private m_DrawIndex As Integer = -1

    Private Sub pbBody_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseDown

        'Initialise Starting Points Of Shape, Once Mouse Button Is Pressed Down
        ' Start a new drawing: increase the counter and redim the arrays
        m_DrawIndex += 1
        ReDim Preserve sStartX(m_DrawIndex)
        ReDim Preserve sStartY(m_DrawIndex)
        ReDim Preserve sEndX(m_DrawIndex)
        ReDim Preserve sEndY(m_DrawIndex)

        sStartX(m_DrawIndex) = e.X
        sStartY(m_DrawIndex) = e.Y

    End Sub

    Private Sub pbBody_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseUp

        'Initialise Ending Points Of Shape, Once Mouse Button Is Released
        sEndX(m_DrawIndex) = e.X
        sEndY(m_DrawIndex) = e.Y

        'Draw The Circle With The Current Starting, And Ending Values.
        'We must subtract the Starting values from the Ending values,
        'to make sure the shape's Starting and ending values are
        'precisely those where you started drawing, and where you
        'ended drawing.
        pbBody.CreateGraphics.DrawEllipse(pPen, sStartX(m_DrawIndex), sStartY(m_DrawIndex), _
                            sEndX(m_DrawIndex) - sStartX(m_DrawIndex), sEndY(m_DrawIndex) - sStartY(m_DrawIndex))

    End Sub

    Private Sub pbBody_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles pbBody.Paint

        'Draw the Final rectangle, as a repaint was issued

        ' Redraw user drawings from the array
        Dim i As Integer

        For i = 0 To m_DrawIndex
            e.Graphics.DrawEllipse(pPen, sStartX(i), sStartY(i), _
                                    sEndX(i) - sStartX(i), sEndY(i) - sStartY(i))
        Next i

    End Sub

    Private Sub btnNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnNext.Click

        Dim connAdd4 As New SqlConnection _
        ("Data Source=152.226.152.99\SQLEXPRESS,1433;" + "Initial Catalog=TAR;" + "User ID=Remote;" + "Password=123;")

        Dim mySQL As String

        'Memory stream        
        Dim ms As New System.IO.MemoryStream
        'Write an image data into memory stream        
        pbBody.Image.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp)

        'Byte array        
        Dim b() As Byte = ms.ToArray
        connAdd4.Open()

        'Parameterized Query        
        mySQL = "insert into image (patientIC,picture) values (@p1,@p2)"
        Dim cmdAdd4 As New SqlCommand(mySQL, connAdd4)

        'Create/add parameters        
        '@p1 - name of parameter, datatype,size,"columnname"       
        cmdAdd4.Parameters.Add("@p1", SqlDbType.VarChar, 50, "patientIC")
        cmdAdd4.Parameters.Add("@p2", SqlDbType.Image, b.Length, "picture")

        'Assign value to the parameters        
        cmdAdd4.Parameters("@p1").Value = txtId.Text
        cmdAdd4.Parameters("@p2").Value = b

        'Execute command        
        cmdAdd4.ExecuteNonQuery()
        connAdd4.Close()

    End Sub
End Class

The above codes manage to save the image and patient's IC to MSSQL (binary data in MSSQL) and the multi selection also works (it wont disappeared when scroll up & down). so do I stil put in the Byte2Image, Image2Byte, SaveByteArray, LoadByteArray or do I just leave it as it was now?

And I don't know what is contain in the binary data when i retrieve as I havent tried.

Btw my retrieval form is different form with this current form , do I stil do the same for the retrieval side in order to see wat is being save in the binary data? as for your codes is retrieval and sendin is in the same form right?

Thanks =)

so do I stil put in the Byte2Image, Image2Byte, SaveByteArray, LoadByteArray or do I just leave it as it was now?

If the code works, don't change it (if it ain't broke, don't fix it, you know ;) ) And like I posted before, Adatapost's code is pretty much same as mine.

And I don't know what is contain in the binary data when i retrieve as I havent tried.

Btw my retrieval form is different form with this current form , do I stil do the same for the retrieval side in order to see wat is being save in the binary data? as for your codes is retrieval and sendin is in the same form right?

I used the same form. That's why I had Button3 to clear the picture box control. It doesn't make any difference if you use another form or even another application to read data back.

In your data retrieval form, copy my Byte2Image and LoadByteArray routines. The Button2_Click event handler contains the rest of the code you need to read image back from the database and put it in the picture box control. That's only three lines of code (without dim and comment lines). Of course you need also connection string etc. from the first form. After that you should have everything ready :)

now the codes are able to show the picture (binary data) that I have save but the picture display doesnt have the pts that i had circle.. :'(

in such case, i tink is the drawing or saving part when wrong isit?

the picture display doesnt have the pts that i had circle

Damn :-O

Ok, I can think of two options. User drawings should be somehow merged to image before saving. They seem to be separate objects right now. I don't have code for that at the moment but I'll try to look for that.

The second option would be to save user drawings separately and repaint them after reading image back from the DB. This would allow the undo operation after saving the image but I believe you would prefer the first solution, right?

ya, i think i prefer the 1st option as it sound easier comparing to the second option and i should be able to understand it better i guess :-/

meanwhile I will try googling if there is codes for merging image and drawing :)

Got it. The very basic principle is not to draw on a (picture box) control. Instead, you have to use some in-memory buffer (i.e. bitmap). You draw to the buffer and then display the buffer in the picture box control. When you save the image to DB, you save the buffer, not picture box's image.

I've used two forms to test it. First form (Form2) is for drawing and it contains just a picture box control and a close button. Second form has a button (Button1) which opens the drawing form and after closing the second form the buffer (bitmap) is saved to DB. ID is taken from a text box control. Second button (Button2) loads the image from the DB and displays it in the second form's picture box control. Here's the drawing form

Option Explicit On
Option Strict On

Public Class Form2

  Public BitmapCanvas As Bitmap

  Private Sub Form2_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    '
    ' Saveing graphics(drawline,drawellipse,ect.) to a file
    ' http://social.msdn.microsoft.com/forums/en-US/vblanguage/thread/0184b1c0-90d0-4660-ba78-a615a8231fe9/
    '
    ' Drawing in VB .Net Win Forms
    ' http://channel9.msdn.com/forums/TechOff/229119-Drawing-in-VB-Net-Win-Forms/

    BitmapCanvas = New Bitmap("D:\image.jpg")
    PictureBox1.Image = BitmapCanvas
    PictureBox1.Invalidate() ' Force redraw

  End Sub

  ' "Drawing" arrays. ARRAYS ARE OBSOLETE NOW, YOU CAN USE "NORMAL" VARIABLES
  Private sStartX() As Integer
  Private sStartY() As Integer
  Private sEndX() As Integer
  Private sEndY() As Integer
  ' Remove New and (Color.White), they're just for debugging
  Private pPen As New System.Drawing.Pen(Color.White) ' DECLARE THIS AS AN ARRAY IF THE PEN CAN BE CHANGED
  ' Counter for the arrays, -1 = nothing drawed yet
  Private m_DrawIndex As Integer = -1

  Private Sub PictureBox1_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseDown

    'Initialise Starting Points Of Shape, Once Mouse Button Is Pressed Down
    ' Start a new drawing: increase the counter and redim the arrays
    m_DrawIndex += 1
    ReDim Preserve sStartX(m_DrawIndex)
    ReDim Preserve sStartY(m_DrawIndex)
    ReDim Preserve sEndX(m_DrawIndex)
    ReDim Preserve sEndY(m_DrawIndex)
    'ReDim Preserve pPen(m_DrawIndex) ' Only if pPen is an array too
    '
    sStartX(m_DrawIndex) = e.X
    sStartY(m_DrawIndex) = e.Y

  End Sub

  Private Sub PictureBox1_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseUp

    Dim Gr As Graphics

    'Initialise Ending Points Of Shape, Once Mouse Button Is Released
    sEndX(m_DrawIndex) = e.X
    sEndY(m_DrawIndex) = e.Y

    'Draw The Circle With The Current Starting, And Ending Values.
    'We must subtract the Starting values from the Ending values,
    'to make sure the shape's Starting and ending values are
    'precisely those where you started drawing, and where you
    'ended drawing.

    ' Get graphics object from the bitmap to draw on
    Gr = Graphics.FromImage(BitmapCanvas)
    ' Draw
    Gr.DrawEllipse(pPen, sStartX(m_DrawIndex), sStartY(m_DrawIndex), _
                        sEndX(m_DrawIndex) - sStartX(m_DrawIndex), sEndY(m_DrawIndex) - sStartY(m_DrawIndex))
    ' Assign bitmap to picture box control
    PictureBox1.Image = BitmapCanvas
    PictureBox1.Invalidate() ' Force redraw

    ' Dispose graphics!
    Gr.Dispose()

  End Sub

  Private Sub cmdClose_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdClose.Click
    '
    Me.Hide()

  End Sub

End Class

A few points. You don't need to trap paint event anymore. Thus you don't need arrays anymore but I didn't fix that. And see the comments in form's load event. There are few links I used.

Here's the "main" form

Option Strict On
Option Explicit On

Imports System.Drawing.Imaging  ' Image related methods etc.
Imports System.IO               ' MemoryStream
Imports System.Data.SqlClient   ' SQl Server related classes

Public Class Form1

  ' Class global variable
  Private m_CnStr As String = "Data Source=.\SQLEXPRESS; INITIAL CATALOG=<dbname>; UID=xxx; Password=xxx;" ' Connection string to DB

  ' Table structure:
  ' ImageTable:
  '
  ' ImageID	  varchar(50)
  ' BlobField image

  ''' <summary>
  ''' Convert a byte array to an Image
  ''' </summary>
  ''' <param name="NewImage">Image to be returned</param>
  ''' <param name="ByteArr">Contains bytes to be converted</param>
  ''' <remarks></remarks>
  Public Sub Byte2Image(ByRef NewImage As Image, ByVal ByteArr() As Byte)
    '
    Dim ImageStream As MemoryStream

    Try
      If ByteArr.GetUpperBound(0) > 0 Then
        ImageStream = New MemoryStream(ByteArr)
        NewImage = Image.FromStream(ImageStream)
      Else
        NewImage = Nothing
      End If
    Catch ex As Exception
      NewImage = Nothing
    End Try

  End Sub

  ''' <summary>
  ''' Convert an image to array of bytes
  ''' </summary>
  ''' <param name="NewImage">Image to be converted</param>
  ''' <param name="ByteArr">Returns bytes</param>
  ''' <remarks></remarks>
  Public Sub Image2Byte(ByVal NewImage As Image, ByRef ByteArr() As Byte)
    '
    Dim ImageStream As MemoryStream

    Try
      ReDim ByteArr(0)
      If NewImage IsNot Nothing Then
        ImageStream = New MemoryStream
        NewImage.Save(ImageStream, ImageFormat.Jpeg)
        ReDim ByteArr(CInt(ImageStream.Length - 1))
        ImageStream.Position = 0
        ImageStream.Read(ByteArr, 0, CInt(ImageStream.Length))
      End If
    Catch ex As Exception

    End Try

  End Sub

  ''' <summary>
  ''' Save a byte array to database
  ''' </summary>
  ''' <param name="ByteArr">Contains bytes to be saved</param>
  ''' <param name="ImageID">ID for the image</param>
  ''' <remarks></remarks>
  Public Sub SaveByteArray(ByVal ByteArr() As Byte, ByVal ImageID As String)
    '
    Dim strSQL As String
    Dim oConn As SqlConnection
    Dim oCmd As SqlCommand
    Dim oVarCharParam As SqlParameter
    Dim oBLOBParam As SqlParameter

    Try
      ' Create and open connection object
      oConn = New SqlConnection(m_CnStr)
      oConn.Open()
      ' Insert statement
      ' Notice that @BLOBValue is a placeholder for the actual data
      strSQL = "INSERT INTO ImageTable (ImageID, BlobField) VALUES (@IDValue, @BLOBValue)"
      ' Create a command object
      oCmd = oConn.CreateCommand()
      ' Set SQL statement
      oCmd.CommandText = strSQL
      ' Create a command parameter
      oVarCharParam = New SqlParameter("@IDValue", SqlDbType.VarChar, _
         50, ParameterDirection.Input.ToString)
      ' Set the actual data
      oVarCharParam.Value = ImageID
      ' Add this parameter to the command
      oCmd.Parameters.Add(oVarCharParam)
      ' Create a command parameter
      oBLOBParam = New SqlParameter("@BLOBValue", SqlDbType.Binary, _
        ByteArr.Length, ParameterDirection.Input.ToString)
      ' Finally, set the actual data
      oBLOBParam.Value = ByteArr
      ' Add this parameter to the command
      oCmd.Parameters.Add(oBLOBParam)
      ' Execute SQL statement
      oCmd.ExecuteNonQuery()
      ' Close the connection
      oConn.Close()
    Catch ex As Exception

    End Try

  End Sub

  ''' <summary>
  ''' Load a byte array from database
  ''' </summary>
  ''' <param name="ByteArr">Contains bytes from the database</param>
  ''' <param name="ImageID">ID for the image</param>
  ''' <remarks></remarks>
  Public Sub LoadByteArray(ByRef ByteArr() As Byte, ByVal ImageID As String)
    '
    Dim strSQL As String
    Dim oConn As SqlConnection
    Dim oCmd As SqlCommand
    Dim ValueFromDB As Object ' ExecuteScalar method returns an object

    Try
      ' Create and open connection object
      oConn = New SqlConnection(m_CnStr)
      oConn.Open()
      ' Select statement
      strSQL = "SELECT BlobField FROM ImageTable WHERE ImageID='" & ImageID & "'"
      ' Create a command object
      oCmd = oConn.CreateCommand()
      ' Set SQL statement
      oCmd.CommandText = strSQL
      ' Execute SQL statement
      ValueFromDB = oCmd.ExecuteScalar()
      ' Close the connection
      oConn.Close()
      ' Convert returned object to an array of bytes
      If ValueFromDB IsNot DBNull.Value Then
        ByteArr = CType(ValueFromDB, Byte())
      End If
    Catch ex As Exception

    End Try

  End Sub

  Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    ' 
    ' DEBUG: Initial ID
    TextBox1.Text = "patient101"

  End Sub

  Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
    ' Saves the image from the bitmap buffer to SQL Server
    Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
    Dim PatientID As String ' ID for the image

    Form2.ShowDialog() ' Draw the image first

    ' Get ID from a text box control and remove spaces
    PatientID = TextBox1.Text.Trim
    ' Convert image to an array of bytes
    ' USE FORM2 BITMAP, NOT PICTURE BOX CONTROL
    Image2Byte(Form2.BitmapCanvas, ImageByteArr)
    ' Save an array of bytes to SQL Server's field of type Image
    SaveByteArray(ImageByteArr, PatientID)

  End Sub

  Private Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
    ' Loads the image to the picture box control from SQL Server
    Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
    Dim PatientID As String ' ID for the image

    ' Get ID from a text box control and remove spaces
    PatientID = TextBox1.Text.Trim
    ' Load an array of bytes from SQL Server's field of type Image
    LoadByteArray(ImageByteArr, PatientID)
    ' Convert an array of bytes to image
    Byte2Image(PictureBox1.Image, ImageByteArr)

  End Sub

End Class

I tried to comment code as best as I could. You should start a new project and test this code. If it works in a way you like, then you can fix your original code.

HTH

sry for the late reply. :)

I would like to ask, am I suppose to be putting picturebox control in my main form and retrieval form so that wat is being drew can be display on picturebox control?

and which is the part of the codes that link form2's drew image into main form and retrieval form?

I didnt manage to get the drawing over to my main form :S

am I suppose to be putting picturebox control in my main form and retrieval form so that wat is being drew can be display on picturebox control?

Just for testing I had a main form (Form1) and a separate drawing form (Form2). You can use just one form. In that case you have to copy the drawing routines from (my) Form2 to your main (drawing) form.

which is the part of the codes that link form2's drew image into main form and retrieval form?

Form1's Button1_Click event opens Form2. Form2 has Public BitmapCanvas As Bitmap . This is a public in-memory buffer (or bitmap) that holds the image and the user drawings, which can be saved to DB. With two forms you have to be careful not to dispose Form2 because then you'll lose that bitmap. If you use only one form, you'll have this in-memory buffer in that form and you don't have a possibility of "loosing" this bitmap.

I didnt manage to get the drawing over to my main form

Did you test the code which I posted "as is"? Or did you modify your previous code? Did you manage to save the image to DB? If the code saves the image then there's still some problem with retrieving the image back from the DB. Anyway, could you please post your current code?

I've tested the example you gave me and it works but when i try to implement it together with my codes, i can manage to save it but i cant retrieve in another form..

codes for drawing:

Public Class DrawingForm

    Public BitmapCanvas As Bitmap

    Private Sub Drawing_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

        BitmapCanvas = New Bitmap("D:\Image\Human Anatomy.JPG")
        pbBody.Image = BitmapCanvas
        pbBody.Invalidate() ' Force redraw

    End Sub

    Private sStartX As Integer
    Private sStartY As Integer
    Private sEndX As Integer
    Private sEndY As Integer

    'Create And Initialise Pens To Draw The Particular Outline Shapes With.  Color : Black, Width : 1
    Dim pPen As New Pen(Color.Black, 1)

    Private Sub pbBody_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseDown

        'Initialise Starting Points Of Shape, Once Mouse Button Is Pressed Down
        sStartX = e.X
        sStartY = e.Y

    End Sub

    Private Sub pbBody_MouseUp(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles pbBody.MouseUp

        Dim Gr As Graphics

        'Initialise Ending Points Of Shape, Once Mouse Button Is Released
        sEndX = e.X
        sEndY = e.Y

        'Draw The Circle With The Current Starting, And Ending Values.
        'We must subtract the Starting values from the Ending values,
        'to make sure the shape's Starting and ending values are
        'precisely those where you started drawing, and where you
        'ended drawing.

        ' Get graphics object from the bitmap to draw on
        Gr = Graphics.FromImage(BitmapCanvas)
        ' Draw
        Gr.DrawEllipse(pPen, sStartX, sStartY, _
                            sEndX - sStartX, sEndY - sStartY)

        ' Assign bitmap to picture box control
        pbBody.Image = BitmapCanvas
        pbBody.Invalidate() ' Force redraw

        ' Dispose graphics!
        Gr.Dispose()

    End Sub

    Private Sub btnDone_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDone.Click

        Me.Hide()

    End Sub

End Class

codes for MainForm:

Imports System.Data
Imports System.Data.SqlClient
Imports System.IO
Imports System.Drawing.Imaging

 Private Sub Page_2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' DEBUG: Initial ID
        txtId.Text = ""

    End Sub

''' <summary>
    ''' Convert an image to array of bytes
    ''' </summary>
    ''' <param name="NewImage">Image to be converted</param>
    ''' <param name="ByteArr">Returns bytes</param>
    ''' <remarks></remarks>
    Public Sub Image2Byte(ByVal NewImage As Image, ByRef ByteArr() As Byte)
        '
        Dim ImageStream As MemoryStream

        Try
            ReDim ByteArr(0)
            If NewImage IsNot Nothing Then
                ImageStream = New MemoryStream
                NewImage.Save(ImageStream, ImageFormat.Jpeg)
                ReDim ByteArr(CInt(ImageStream.Length - 1))
                ImageStream.Position = 0
                ImageStream.Read(ByteArr, 0, CInt(ImageStream.Length))
            End If
        Catch ex As Exception

        End Try

    End Sub

    ''' <summary>
    ''' Save a byte array to database
    ''' </summary>
    ''' <param name="ByteArr">Contains bytes to be saved</param>
    ''' <param name="patientIC">ID for the image</param>
    ''' <remarks></remarks>
    Public Sub SaveByteArray(ByVal ByteArr() As Byte, ByVal patientIC As String)
        '
        Dim mySQL As String
        Dim cmdAdd4 As SqlCommand
        Dim oVarCharParam As SqlParameter
        Dim oBLOBParam As SqlParameter

        Try
            ' Create and open connection object
            Dim connAdd4 As New SqlConnection _
                ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")
            connAdd4.Open()
            ' Insert statement
            ' Notice that @BLOBValue is a placeholder for the actual data
            mySQL = "INSERT INTO image (patientIC, picture) VALUES (@IDValue, @BLOBValue)"
            ' Create a command object
            cmdAdd4 = connAdd4.CreateCommand()
            ' Set SQL statement
            cmdAdd4.CommandText = mySQL
            ' Create a command parameter
            oVarCharParam = New SqlParameter("@IDValue", SqlDbType.VarChar, _
               50, ParameterDirection.Input.ToString)
            ' Set the actual data
            oVarCharParam.Value = patientIC
            ' Add this parameter to the command
            cmdAdd4.Parameters.Add(oVarCharParam)
            ' Create a command parameter
            oBLOBParam = New SqlParameter("@BLOBValue", SqlDbType.Binary, _
              ByteArr.Length, ParameterDirection.Input.ToString)
            ' Finally, set the actual data
            oBLOBParam.Value = ByteArr
            ' Add this parameter to the command
            cmdAdd4.Parameters.Add(oBLOBParam)
            ' Execute SQL statement
            cmdAdd4.ExecuteNonQuery()
            ' Close the connection
            connAdd4.Close()
        Catch ex As Exception

        End Try

    End Sub

    Private Sub btnOpen_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnOpen.Click

        Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
        Dim patientIC As String ' ID for the image

        Drawing.ShowDialog() ' Draw the image first

        ' Get ID from a text box control and remove spaces
        patientIC = txtId.Text.Trim
        ' Convert image to an array of bytes
        Image2Byte(pbBody.Image, ImageByteArr)
        ' Save an array of bytes to SQL Server's field of type Image
        SaveByteArray(ImageByteArr, patientIC)

    End Sub

codes for RetrievalForm:

Imports System.Drawing.Imaging  ' Image related methods etc.
Imports System.IO               ' MemoryStream
Imports System.Data.SqlClient   ' SQl Server related classes
Imports System.Data

Public Class Page2

    ''' <summary>
    ''' Convert a byte array to an Image
    ''' </summary>
    ''' <param name="NewImage">Image to be returned</param>
    ''' <param name="ByteArr">Contains bytes to be converted</param>
    ''' <remarks></remarks>
    Public Sub Byte2Image(ByRef NewImage As Image, ByVal ByteArr() As Byte)
        '
        Dim ImageStream As MemoryStream

        Try
            If ByteArr.GetUpperBound(0) > 0 Then
                ImageStream = New MemoryStream(ByteArr)
                NewImage = Image.FromStream(ImageStream)
            Else
                NewImage = Nothing
            End If
        Catch ex As Exception
            NewImage = Nothing
        End Try

    End Sub

    ''' <summary>
    ''' Load a byte array from database
    ''' </summary>
    ''' <param name="ByteArr">Contains bytes from the database</param>
    ''' <param name="patientIC">Patient's IC for Image</param>
    ''' <remarks></remarks>
    Public Sub LoadByteArray(ByRef ByteArr() As Byte, ByVal patientIC As String)
        '
        Dim mySQL As String
        Dim cmdGet4 As SqlCommand
        Dim ValueFromDB As Object ' ExecuteScalar method returns an object

        Try
            ' Create and open connection object
            Dim connGet4 As New SqlConnection _
                ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")
            connGet4.Open()

            ' Select statement
            mySQL = "SELECT picture FROM image WHERE patientIC='" & Trim(txtId.Text) & "'"
            ' Create a command object
            cmdGet4 = connGet4.CreateCommand()
            ' Set SQL statement
            cmdGet4.CommandText = mySQL
            ' Execute SQL statement
            ValueFromDB = cmdGet4.ExecuteScalar()
            ' Close the connection
            connGet4.Close()

            ' Convert returned object to an array of bytes
            If ValueFromDB IsNot DBNull.Value Then
                ByteArr = CType(ValueFromDB, Byte())
            End If
        Catch ex As Exception

        End Try

    End Sub

    Private Sub btnSearch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSearch.Click

        Dim connGet As New SqlConnection _
        ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")

        Dim connGet1 As New SqlConnection _
        ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")

        Dim connGet2 As New SqlConnection _
        ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")

        Dim connGet3 As New SqlConnection _
        ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")

        connGet.Open()
        Dim cmdGet As New SqlCommand("select * from gcs where patientIC = '" & Trim(txtId.Text) & "'", connGet)
        Dim dr As SqlDataReader
        dr = cmdGet.ExecuteReader()

        If dr.Read() Then
            lblEyes.Text = dr("eyesOpen")
            lblVerbal.Text = dr("verbal")
            lblMotor.Text = dr("motor")
            lblTotalGCS.Text = dr("totalGcs")
        End If

        dr.Close()
        connGet.Close()

        connGet1.Open()
        Dim cmdGet1 As New SqlCommand("select * from vitalSign where patientIC = '" & Trim(txtId.Text) & "'", connGet1)
        Dim dr1 As SqlDataReader
        dr1 = cmdGet1.ExecuteReader()

        If dr1.Read() Then
            lblPulse.Text = dr1("pulse")
            lblRespiration.Text = dr1("respiration")
            lblSystolic.Text = dr1("systolic")
            lblDiastolic.Text = dr1("diastolic")
            lblMean.Text = dr1("mean")
            lblSpo2.Text = dr1("spo2")
            lblTemperature.Text = dr1("temperature")
        End If

        dr1.Close()
        connGet1.Close()

        connGet2.Open()
        Dim cmdGet2 As New SqlCommand("select * from respiratoryAssist where patientIC = '" & Trim(txtId.Text) & "'", connGet2)
        Dim dr2 As SqlDataReader
        dr2 = cmdGet2.ExecuteReader()

        If dr2.Read() Then
            lblIntubationSize.Text = dr2("iSize")
            lblIntubationMarking.Text = dr2("marking")
            lblIntubation.Text = dr2("intubation")
            lblChestTubeSize.Text = dr2("cSize")
            lblChestTube.Text = dr2("chestTube")
        End If

        dr2.Close()
        connGet2.Close()

        connGet3.Open()
        Dim cmdGet3 As New SqlCommand("select * from drain where patientIC = '" & Trim(txtId.Text) & "'", connGet3)
        Dim dr3 As SqlDataReader
        dr3 = cmdGet3.ExecuteReader()

        If dr3.Read() Then
            lblNasogastricTube.Text = dr3("nasogastricTube")
            lblUrinaryCatheter.Text = dr3("urinaryCatheter")
            lblLtArm.Text = dr3("ivPlugLeft")
            lblRtArm.Text = dr3("ivPlugRight")
            lblOthers.Text = dr3("others")
        End If

        dr3.Close()
        connGet3.Close()

        ' Loads the image to the picture box control from SQL Server
        Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
        Dim patientIC As String ' Patient's IC for Image

        ' Get ID from a text box control and remove spaces
        patientIC = txtId.Text.Trim
        ' Load an array of bytes from SQL Server's field of type Image
        LoadByteArray(ImageByteArr, patientIC)
        ' Convert an array of bytes to image
        Byte2Image(pbBody.Image, ImageByteArr)

    End Sub

    Private Sub Page2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ' DEBUG: Initial ID
        txtId.Text = ""

    End Sub
End Class

* for RetrievalForm, i hav include the codes that i need to retrieve (other info besides the drawing part).

i duno wat went wrong whereby ur example works but not on my codes.

however i also try putting the drawing part and main form into 1 form but i didnt manage to get it worked.

i duno wat went wrong whereby ur example works but not on my codes.

I tested your code and it worked fine (Page2 form's code). I had to comment out all the data retrieval for labels to test btnSearch_Click but I don't believe that effects anything.

First, you did have a valid value for PatientIC (txtId control)?

Secondly. In

Dim connGet4 As New SqlConnection _
   ("Data Source=DATASOURCE;" + "Initial Catalog=TABLENAME;" + "User ID=UID;" + "Password=PW;")

Initial Catalog=TABLENAME refers to database, not a table in the database. For example, If you have a DB called Patient and a table called Images, your Initial Catalog=Patient.

Here's a modified code for debugging (replace last few lines in btnSearch_Click event handler)

' Loads the image to the picture box control from SQL Server
Dim ImageByteArr(0) As Byte ' An array to hold image (bytes)
Dim patientIC As String ' Patient's IC for Image

' Get ID from a text box control and remove spaces
patientIC = txtId.Text.Trim
' Load an array of bytes from SQL Server's field of type Image
LoadByteArray(ImageByteArr, patientIC)
If ImageByteArr.Length < 1 Then
  MsgBox("Empty byte array! patientIC='" & patientIC & "' might not exist?")
End If
' Convert an array of bytes to image
Dim TempImage As Image = Nothing
Byte2Image(TempImage, ImageByteArr)
If TempImage IsNot Nothing Then
  pbBody.Image = TempImage
Else
  MsgBox("Image is nothing!")
End If

If your app can't find the data in the first place (patientIC does not exist) you should get: "Empty byte array! patientIC=..." message. In that case, check the ID you're using. You could use SQL Server Management Studio or similar to check directly from the DB those patientIC values. I assume patientIC is of type VarChar. If you've declared it Char or NChar, the string inserted to that field gets padded with spaces! One more warning of text fields. If the user enters an apostrophe ('-character) to the ID field, your code might crash quite easily.

If the conversion from bytes to image fails, you'll get "Image is nothing!" message but I doubt that there's any bug.

i also try putting the drawing part and main form into 1 form but i didnt manage to get it worked

I suggest debugging the code as it is right now. After everything works fine, merge the codes from those two forms to a one form (remember to take a backup copy from your working code first!). The app should work just fine in a single form.

I have check the DB and there is this patientIC in my DB and also binary data but when i try to retrieve, it say "Image is nothing" whereby other info that stored in that database can be retrieve except for the image only :'(

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.