Error saving resized bitmap

T

tjonsek

I get a generic error (not very helpful) when attempting to save a
re-sized image back to its original location. Here is the code snippet:

Dim g As System.Drawing.Image =
System.Drawing.Image.FromFile(Me.File1.Value)
Dim thisFormat = g.RawFormat
Dim imgOutput As New Bitmap(g, 800, 600)
Dim strFileType As String

Dim strFileName As String = File1.PostedFile.FileName

' only the attched file name not its path
Dim c As String = System.IO.Path.GetFileName(strFileName)

imgOutput.Save(strFileName)

The last line seems to throw the error. With a hard coded path, I don't
get an error so I think somehow I am missing something. The only
difference is the missing ("") around the strFileName vs. a hard coded
path.

Any ideas?
Thank you and I appreciate your help.
 
G

gazza

It looks like you are trying to upload a file from your client and then
save it to an equivalent directory on the server. I don't think that's
what you intended. You need to save it to a mapped path on the server
(one with write permissions) and then download it to the original
location on the client... I think :)

Gary
 
T

tjonsek

Ok. What you say makes sense. But how do I download it to the original
location?

What I'd like to do is take the new bitmap and save it to a SQL Server
database. (I can already hear a dozen people telling me its easier NOT
to do that, but it's the project requirement - my hands are tied).

I can save to a databse from the htmlinputfile control, but am
struggling with adapting it to the bitmap I've created.
What should be happening is that I take an image, if it is greater than
a certain size, resize it and then save it to the database. I can
resize the image and save it to the server. I can take an image and
upload it to a database. But I can't seem to take the image, resize it
and then save the new version to the database.

I appreciate the help!

Currently, I'm trying to adapt my functions to pull the data I need
from the bitmap rather than the input control.
However, I thought 'wouldn't it be cool, if I could take the image,
resize it, save the new version to the same location already in the
file input control and then upload it to the database'

Sounds good but not working.
 
G

gazza

I think you're complicating things - just write the resized file out to
a mapped server path, store it in your SQL server and then delete the
file. Don't worry about overwriting the posted file, AFAIK it does not
live anywhere on the server other than in memory (happy to be
corrected) until you physically save it. Obviously the original image
on the client will be unchanged, but I assume you don't care about
that.

All the best,

Gary
 
M

Mythran

I think you're complicating things - just write the resized file out to
a mapped server path, store it in your SQL server and then delete the
file. Don't worry about overwriting the posted file, AFAIK it does not
live anywhere on the server other than in memory (happy to be
corrected) until you physically save it. Obviously the original image
on the client will be unchanged, but I assume you don't care about
that.

All the best,

Gary

If you are going to store the image into a field/record on SQL Server, you
don't need to write the file to disk on the server first. When you get it
into an Image object, save the image to a MemoryStream. From there, read
from the memory stream into a byte-array and store that data in the "image"
field in SQL Server.

Mythran
 
T

tjonsek

Thanks! The MemoryStream was what I was lacking.
And I also didn't think about the convenience of storing the file on
the server and then deleting, that would have been a little more
helpful as well.

But to add - I did find that if I simply disposed of the original
graphic (g.dispose()), I was able to save to the original location.
However that didn't help either. Because I did not know how to get the
image to a stream of some type to a byte array (as I was doing with the
input file), I was simply trying to think out of the box for another
way around the obstacle.

I appreciate the help all around.
 
T

tjonsek

One more quick question -
I've done some researching and can't seem to find a straight answer to
this. In the following code, how do I actually save to the stream?
Here is what I have:
Dim intFileLength As Integer, bytData() As Byte
Dim objStream As System.IO.MemoryStream
'If FileFieldSelected(FileField) Then
intFileLength = FileField.PropertyItems.Length
ReDim bytData(intFileLength)
objStream = ?????? 'Don't know what goes here
objStream.Read(bytData, 0, intFileLength)
Return bytData

With the input file, I have this: objStream =
FileField.PostedFile.InputStream

My suspicion is to save it like this: FileField.Save(objStream,
Imaging.ImageFormat.Jpeg)
 
T

tjonsek

One more quick question -
I've done some researching and can't seem to find a straight answer to
this. In the following code, how do I actually save to the stream?
Here is what I have:
Dim intFileLength As Integer, bytData() As Byte
Dim objStream As System.IO.MemoryStream
'If FileFieldSelected(FileField) Then
intFileLength = FileField.PropertyItems.Length
ReDim bytData(intFileLength)
objStream = ?????? 'Don't know what goes here
objStream.Read(bytData, 0, intFileLength)
Return bytData

With the input file, I have this: objStream =
FileField.PostedFile.InputStream

My suspicion is to save it like this: FileField.Save(objStream,
Imaging.ImageFormat.Jpeg)
 
T

tjonsek

That's where it gets tricky and thanks for the function, but I have
taken a posted file, created a new bitmap from the file and resized it
and then I want to get the info from the new bitmap. I can't seem to
get the byte-array from the bitmap. Currently, this is what I have:

Public Function GetByteArrayFromBitmap( _
ByVal FileField As System.Drawing.Bitmap) _
As Byte()
' Returns a byte array from the passed
' bitmap
Dim intFileLength As Integer
Dim objStream As System.IO.MemoryStream


FileField.Save(objStream, Imaging.ImageFormat.Jpeg)
Dim bytData(objStream.Length) As Byte
intFileLength = bytData.Length
objStream.Read(bytData, 0, intFileLength)
Return bytData
End Function

It doesn't work because my objStream is NULL. I get this error: Value
can't be null: Parameter name: stream.
I know I haven't done something right. I tried saving the new bitmap to
the original location, that worked, but when I upload the file to the
database, it's still the original copy of the file instead of the new
version. I think somehow the header info or something stays in memory
and when I continue to work with the input file control it references
the original information.

I really appreciate your help.
 
M

Mythran

That's where it gets tricky and thanks for the function, but I have
taken a posted file, created a new bitmap from the file and resized it
and then I want to get the info from the new bitmap. I can't seem to
get the byte-array from the bitmap. Currently, this is what I have:

Public Function GetByteArrayFromBitmap( _
ByVal FileField As System.Drawing.Bitmap) _
As Byte()
' Returns a byte array from the passed
' bitmap
Dim intFileLength As Integer
Dim objStream As System.IO.MemoryStream


FileField.Save(objStream, Imaging.ImageFormat.Jpeg)
Dim bytData(objStream.Length) As Byte
intFileLength = bytData.Length
objStream.Read(bytData, 0, intFileLength)
Return bytData
End Function

It doesn't work because my objStream is NULL. I get this error: Value
can't be null: Parameter name: stream.

Yup, you haven't instantiated an instance of the MemoryStream class...

objStream = New System.IO.MemoryStream()

So, your dim statement should look similar to:

Dim objStream As System.IO.MemoryStream = New System.IO.MemoryStream()

HTH :)

Mythran
 
T

tjonsek

You're right. I needed to do that, but even after I still had a few
issues. However, all is working now. So if others have this same
problem in the future, here is the abbreviated version of the code:

Dim intFileLength As Integer
Dim objStream As System.IO.MemoryStream = New
System.IO.MemoryStream
imgOutput.Save(objStream, Imaging.ImageFormat.Jpeg)
Dim bytData(objStream.Length) As Byte
intFileLength = bytData.Length
Dim intVar As Integer


bytData = objStream.GetBuffer


I had to use 'bytData = objStream.GetBuffer' rather than
'objStream.Read(bytData, 0, intFileLength)'
 
M

Mythran

You're right. I needed to do that, but even after I still had a few
issues. However, all is working now. So if others have this same
problem in the future, here is the abbreviated version of the code:

Dim intFileLength As Integer
Dim objStream As System.IO.MemoryStream = New
System.IO.MemoryStream
imgOutput.Save(objStream, Imaging.ImageFormat.Jpeg)
Dim bytData(objStream.Length) As Byte
intFileLength = bytData.Length
Dim intVar As Integer


bytData = objStream.GetBuffer


I had to use 'bytData = objStream.GetBuffer' rather than
'objStream.Read(bytData, 0, intFileLength)'

Your byte array is including an empty byte at the end of the array because
of how you are dimensioning it.

Dim bytData(...) AS Byte should be...

Dim bytData(objStream.Length - 1) As Byte

OR

Dim bytData As Byte() = New Byte(objStream.Length - 1) { }

:)

Cheers!

Mythran
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,989
Messages
2,570,207
Members
46,785
Latest member
undedgini

Latest Threads

Top