CISS
asked on
VB.Net how to convert memory stream into jpg on compact framework
I’m using some code that I got off dev buzz to capture a signature in a windows mobile application. I need to be able to save the data to a local sqlce database and post it via a web service so I can display the signature on packing list. The datatype on the database field is image. Currently the raw data is being stored into the database but I would like to convert it into a jpg prior to storing it in the database. How do I convert “stream” into a jpg prior to the save?
Dim stream As System.IO.MemoryStream = _
New System.IO.MemoryStream(_si gnature.Si gnatureBit s)
Dim sigLength As Int32 = CInt(stream.Length)
Dim strsql As String = String.Empty
If Not bRunOnce Then
strsql = "insert into Signatures (ID, DateCreated, Signature) VALUES (@ID, GetDate(), @Signature)"
bRunOnce = True
Else
strsql = "update Signatures set DateCreated = getdate(), Signature = @Signature where ID = @ID"
End If
Dim myCommand As New SqlCeCommand(strsql, myConn)
Dim param As SqlCeParameter = Nothing
param = New SqlCeParameter("@ID", Data.SqlDbType.Int)
myCommand.Parameters.Add(p aram)
myCommand.Parameters("@ID" ).Size = 4
myCommand.Parameters("@ID" ).Value = 1
If sigLength = 0 Then
param = New SqlCeParameter("@Signature ", Data.SqlDbType.Image)
myCommand.Parameters.Add(p aram)
myCommand.Parameters("@Sig nature").S ize = 0
myCommand.Parameters("@Sig nature").V alue = DBNull.Value
Else
param = New SqlCeParameter("@Signature ", Data.SqlDbType.Image)
myCommand.Parameters.Add(p aram)
myCommand.Parameters("@Sig nature").S ize = stream.ToArray().Length
myCommand.Parameters("@Sig nature").V alue = stream.ToArray()
End If
myCommand.ExecuteNonQuery( )
sbar.Text = "Signature saved!"
Catch ex As Exception
sbar.Text = "Signature did not save!"
MsgBox("Error: " & ex.Message)
Finally
Dim stream As System.IO.MemoryStream = _
New System.IO.MemoryStream(_si
Dim sigLength As Int32 = CInt(stream.Length)
Dim strsql As String = String.Empty
If Not bRunOnce Then
strsql = "insert into Signatures (ID, DateCreated, Signature) VALUES (@ID, GetDate(), @Signature)"
bRunOnce = True
Else
strsql = "update Signatures set DateCreated = getdate(), Signature = @Signature where ID = @ID"
End If
Dim myCommand As New SqlCeCommand(strsql, myConn)
Dim param As SqlCeParameter = Nothing
param = New SqlCeParameter("@ID", Data.SqlDbType.Int)
myCommand.Parameters.Add(p
myCommand.Parameters("@ID"
myCommand.Parameters("@ID"
If sigLength = 0 Then
param = New SqlCeParameter("@Signature
myCommand.Parameters.Add(p
myCommand.Parameters("@Sig
myCommand.Parameters("@Sig
Else
param = New SqlCeParameter("@Signature
myCommand.Parameters.Add(p
myCommand.Parameters("@Sig
myCommand.Parameters("@Sig
End If
myCommand.ExecuteNonQuery(
sbar.Text = "Signature saved!"
Catch ex As Exception
sbar.Text = "Signature did not save!"
MsgBox("Error: " & ex.Message)
Finally
ASKER
I tried that but it throws the following exception
ex.Message "Value does not fall within the expected range." String
Here's my code
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s)
Try
bmp = New Bitmap(stream)
Catch ex As Exception
Dim s_message As String = ex.Message
Finally
End Try
ex.Message "Value does not fall within the expected range." String
Here's my code
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si
Try
bmp = New Bitmap(stream)
Catch ex As Exception
Dim s_message As String = ex.Message
Finally
End Try
Try changing
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s)
to
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s.ToArray)
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si
to
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si
ASKER
SignatureBits Method returns Byte. When I try .ToArray I get the following exception
value of type '1-demensional array of byte' cannot be converted to 'system.io.memorystream'
Public ReadOnly Property SignatureBits() As Byte()
Get
Return SignatureData.GetBytes(Me. Width, Me.Height, _lines)
End Get
End Property
value of type '1-demensional array of byte' cannot be converted to 'system.io.memorystream'
Public ReadOnly Property SignatureBits() As Byte()
Get
Return SignatureData.GetBytes(Me.
End Get
End Property
Oh its a byte array already.
> "Value does not fall within the expected range."
Which line produces the error?
> "Value does not fall within the expected range."
Which line produces the error?
ASKER
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s).ToArray () Intellisense highlights the line and provides the feed back
I was talking about this error
> "Value does not fall within the expected range."
with
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s)
And by the way, my suggestion was
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s.ToArray())
and NOT
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si gnature.Si gnatureBit s).ToArray()
> "Value does not fall within the expected range."
with
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si
And by the way, my suggestion was
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si
and NOT
Dim stream As System.IO.MemoryStream = New System.IO.MemoryStream(_si
in that devbuzz example, _signature.SignatureBits is a property returning Byte(), so it IS already an array :)
I used that sample but in c#. In case of VB.NET, it's possible that it handles large numbers incorrectly unlike c#.
Try
stream.Read(_signature.Sig natureBits ,0,_signat ure.Signat ureBits.Le ngth)
instead, or even read it in a loop (1 byte at time) to see when it fails.
I used that sample but in c#. In case of VB.NET, it's possible that it handles large numbers incorrectly unlike c#.
Try
stream.Read(_signature.Sig
instead, or even read it in a loop (1 byte at time) to see when it fails.
ASKER
Getting closer doesn't throw an error but only produces a black jpg.
Dim bmp As New Bitmap(200, 100)
path = System.IO.Path.GetDirector yName(Syst em.Reflect ion.Assemb ly.GetExec utingAssem bly().Mani festModule .FullyQual ifiedName)
Try
path += "\bitmap.bmp"
Cursor.Current = Cursors.WaitCursor
sbar.Text = "Saving signature..."
Dim stream As New System.IO.MemoryStream
stream.Read(_signature.Sig natureBits , 0, _signature.SignatureBits.L ength)
Try
bmp.Save(stream, System.Drawing.Imaging.Ima geFormat.B mp)
bmp.Save(path, System.Drawing.Imaging.Ima geFormat.B mp)
Catch ex As Exception
Dim s_message As String = ex.Message
Finally
End Try
Dim bmp As New Bitmap(200, 100)
path = System.IO.Path.GetDirector
Try
path += "\bitmap.bmp"
Cursor.Current = Cursors.WaitCursor
sbar.Text = "Saving signature..."
Dim stream As New System.IO.MemoryStream
stream.Read(_signature.Sig
Try
bmp.Save(stream, System.Drawing.Imaging.Ima
bmp.Save(path, System.Drawing.Imaging.Ima
Catch ex As Exception
Dim s_message As String = ex.Message
Finally
End Try
add the following to signature class:
Public Function ScaleImage(ByVal width As Integer, ByVal height As Integer) As Bitmap
Dim result As New Bitmap(width, height)
Using g As Graphics = Graphics.FromImage(result)
Dim dstRect As New Rectangle(0, 0, width, height)
Dim srcRect As New Rectangle(0, 0, _bmp.Width, _bmp.Height)
g.DrawImage(_bmp, dstRect, srcRect, GraphicsUnit.Pixel)
End Using
Return result
End Function
and it will be OK :)
Public Function ScaleImage(ByVal width As Integer, ByVal height As Integer) As Bitmap
Dim result As New Bitmap(width, height)
Using g As Graphics = Graphics.FromImage(result)
Dim dstRect As New Rectangle(0, 0, width, height)
Dim srcRect As New Rectangle(0, 0, _bmp.Width, _bmp.Height)
g.DrawImage(_bmp, dstRect, srcRect, GraphicsUnit.Pixel)
End Using
Return result
End Function
and it will be OK :)
What is _bmp?
here's the original sample I think: http://forums.devbuzz.com/m_41070/mpage_1/key_/tm.htm#41070
but basically, _bmp is
Private _bmp As Bitmap
but basically, _bmp is
Private _bmp As Bitmap
So drawing one empty image onto another empty image?
ASKER
alexy you da man!! That did the trick. we're almost home there are actually 2 images streamed in the code. The inbound side before storing in the database has a splash screen that says "please sign here" thats where we placed the above code. I actually need the image that comes back from. Sorry I placed the code in the wrong order of events.
Private Sub redrawSig(ByVal thisSigData As SignatureData)
Dim _graphics As Graphics
_graphics = Graphics.FromImage(_signat ure.Bmp)
DrawSignature(_graphics, thisSigData)
_signature.Invalidate()
Private Sub redrawSig(ByVal thisSigData As SignatureData)
Dim _graphics As Graphics
_graphics = Graphics.FromImage(_signat
DrawSignature(_graphics, thisSigData)
_signature.Invalidate()
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thank you so much it is greatly appreciated
Dim bmp As New Bitmap(stream)