prototye
asked on
VB.NET Picture into class variable looses file information
Hi,
I'm having a problem with file information being lost, and am getting Parameter is not valid when trying to get any of the picture attibutes, after having loaded the picture from file into a variable. When initially adding the picture into a new class, the file info is there until the New constructor has finished. Please see the below pictures
I'm having a problem with file information being lost, and am getting Parameter is not valid when trying to get any of the picture attibutes, after having loaded the picture from file into a variable. When initially adding the picture into a new class, the file info is there until the New constructor has finished. Please see the below pictures
Please post the entire relevant code. It is difficult to see the big picture from a few select screenshots : \
Post more complete code, not screenshots.
From MSDN
http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx
So problem seems to be that you are closing the image stream which you should not.
Remarks
You must keep the stream open for the lifetime of the Image.
http://msdn.microsoft.com/en-us/library/93z9ee4x.aspx
So problem seems to be that you are closing the image stream which you should not.
ASKER
Please find the code below, with various methods I thried to implement commented out. The reason I close the stream is that I don't want any lock on the file. Should that be a problem if I use the New Bitmap (Filepath) sytnax? Why would the image properties still be ok after I closed the memory stream before I left the class (using the New(pFilePath As String, pPropertyCode As String, pSortOrder As Long) constuctor)
Imports System.ComponentModel
Imports System.Data.SqlClient
Imports System.Data
Imports System.IO
Imports System.Drawing.Imaging
Public Class PropertyImage
#Region "Private Members"
Private mPropertyImageID As Long
Private mPropertyCode As String = ""
Private mImagePath As String = ""
Private mSortOrder As Long
Private mActive As Boolean
Private mImageData As Bitmap
Private mImageSmall1 As Bitmap
Private Const SizeSetting1 As Long = 150
#End Region
#Region "Properties"
<DataObjectFieldAttribute(True, True, False)> _
Public Property PropertyImageID As Long
Get
Return mPropertyImageID
End Get
Set(value As Long)
mPropertyImageID = value
End Set
End Property
Public Property PropertyCode As String
Get
Return mPropertyCode
End Get
Set(ByVal value As String)
mPropertyCode = value
End Set
End Property
Public Property ImagePath As String
Get
Return mImagePath
End Get
Set(ByVal value As String)
mImagePath = value
End Set
End Property
Public Property ImageData As Bitmap
Get
'If mImageData Is Nothing And ImagePath.Length > 0 Then
' LoadExisting()
'End If
Return mImageData
End Get
Set(value As Bitmap)
mImageData = value
End Set
End Property
Public Property ImageSmall1 As Bitmap
Get
If mImageSmall1 Is Nothing Then
LoadSmall1()
End If
Return mImageSmall1
End Get
Set(value As Bitmap)
mImageSmall1 = value
End Set
End Property
Public Property SortOrder As Long
Get
Return mSortOrder
End Get
Set(value As Long)
mSortOrder = value
End Set
End Property
Public Property Active As Boolean
Get
Return mActive
End Get
Set(value As Boolean)
mActive = value
End Set
End Property
#End Region
#Region "Constuctors"
Public Sub New()
End Sub
Public Sub New(pFilePath As String, pPropertyCode As String, pSortOrder As Long)
If LoadNewFromFile(pFilePath) Then
PropertyCode = pPropertyCode
SortOrder = pSortOrder
Active = True
End If
End Sub
Public Sub New(ByRef objReader As SqlDataReader)
LoadFromReader(objReader)
End Sub
#End Region
#Region "Image File IO"
Private Function LoadNewFromFile(pFilePath As String) As Boolean
Try
If File.Exists(pFilePath) = False Then Return False
'Dim limageStream As MemoryStream = New MemoryStream(
Dim ImageStream As New FileStream(pFilePath, FileMode.Open, FileAccess.Read)
'ImageData = ResizeImage(ImageStream, 0)
ImageData = Image.FromStream(ImageStream)
ImageStream.Close()
'Dim img As Image = Image.FromFile(pFilePath)
'Dim lImage As New Bitmap(ImageStream)
'ImageData = GetNewImage(lImage)
'ImageStream.Close()
''ImageStream.Dispose()
'lImage = Nothing
Return True
Catch ex As Exception
MsgBox(ex.ToString)
Return False
End Try
End Function
Private Function LoadExisting() As Boolean
If File.Exists(ImagePath) = False Then Return False
Dim lImage As New Bitmap(ImagePath)
ImageData = GetNewImage(lImage)
lImage = Nothing
Return True
End Function
Private Function LoadSmall1() As Boolean
If ImageData Is Nothing Then Return False
ImageSmall1 = GetNewImage(ImageData, 1)
Return True
End Function
Public Function SaveToFile(strFileName)
ImageData.Save(strFileName)
Return True
End Function
#End Region
#Region "Image Resizing and Manipulation"
Private Function GetNewImage(ByVal originalImage As Bitmap, Optional ByVal SizeSetting As Long = 0) As Bitmap
Dim newImage As Bitmap
If ImageNeedsResizing(originalImage.Width, originalImage.Height, SizeSetting) Then
newImage = ResizeImage(originalImage, SizeSetting)
Else
newImage = New Bitmap(originalImage, originalImage.Width, originalImage.Height)
End If
originalImage.Dispose()
Return newImage
End Function
Public Overloads Function ResizeImage(ByVal pImage As Bitmap, SizeSetting As Long) As Bitmap
Dim newImage As New Bitmap(pImage, NewWidth(pImage.Width, pImage.Height, SizeSetting), NewHeight(pImage.Width, pImage.Height, SizeSetting))
Dim g As Graphics = Graphics.FromImage(newImage)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear
g.DrawImage(pImage, 0, 0, newImage.Width, newImage.Height)
pImage.Dispose()
Return newImage
End Function
Public Overloads Function ResizeImage(ByVal streamImage As Stream, SizeSetting As Long) As Bitmap
Dim pImage As Bitmap
pImage = Image.FromStream(streamImage)
Dim newImage As New Bitmap(pImage, NewWidth(pImage.Width, pImage.Height, SizeSetting), NewHeight(pImage.Width, pImage.Height, SizeSetting))
Dim g As Graphics = Graphics.FromImage(newImage)
g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear
g.DrawImage(pImage, 0, 0, newImage.Width, newImage.Height)
pImage.Dispose()
Return newImage
End Function
Private Function NewWidth(OrginalWidth As Int32, OriginalHeight As Int32, SizeSetting As Long) As Int32
Dim lMaxSize1 As Integer = 1024, lMaxSize2 As Integer = 768
If SizeSetting = 1 Then
lMaxSize1 = SizeSetting1
lMaxSize2 = SizeSetting1
End If
Dim divideBy, divideByH, divideByW As Double
divideByW = OrginalWidth / lMaxSize1
divideByH = OriginalHeight / lMaxSize1
If divideByW > divideByH Then
divideBy = divideByW
If (OriginalHeight / divideBy) > lMaxSize2 Then
divideBy = OriginalHeight / lMaxSize2
End If
Else
divideBy = divideByH
If (OrginalWidth / divideBy) > lMaxSize2 Then
divideBy = OrginalWidth / lMaxSize2
End If
End If
If divideBy <= 1 Then Return OrginalWidth
Return OrginalWidth / divideBy
End Function
Private Function NewHeight(OrginalWidth As Int32, OriginalHeight As Int32, SizeSetting As Long) As Int32
Dim lMaxSize1 As Integer = 1024, lMaxSize2 As Integer = 768
If SizeSetting = 1 Then
lMaxSize1 = SizeSetting1
lMaxSize2 = SizeSetting1
End If
Dim divideBy, divideByH, divideByW As Double
divideByW = OrginalWidth / lMaxSize1
divideByH = OriginalHeight / lMaxSize1
If divideByW > divideByH Then
divideBy = divideByW
If (OriginalHeight / divideBy) > lMaxSize2 Then
divideBy = OriginalHeight / lMaxSize2
End If
Else
divideBy = divideByH
If (OrginalWidth / divideBy) > lMaxSize2 Then
divideBy = OrginalWidth / lMaxSize2
End If
End If
If divideBy <= 1 Then Return OriginalHeight
Return OriginalHeight / divideBy
End Function
Private Function ImageNeedsResizing(OrginalWidth As Int32, OriginalHeight As Int32, SizeSetting As Long) As Boolean
If OriginalHeight = NewHeight(OrginalWidth, OriginalHeight, SizeSetting) And OrginalWidth = NewWidth(OrginalWidth, OriginalHeight, SizeSetting) Then Return False
Return True
End Function
#End Region
#Region "DB Operations"
Private Function LoadFromReader(ByRef objReader As SqlDataReader) As Boolean
Try
PropertyImageID = objReader(objReader.GetOrdinal("PropertyImageID"))
PropertyCode = objReader(objReader.GetOrdinal("PropertyCode"))
Active = objReader(objReader.GetOrdinal("Active"))
SortOrder = objReader(objReader.GetOrdinal("SortOrder"))
Return True
Catch ex As Exception
gHandleError.ERROR_LOG(System.Reflection.MethodBase.GetCurrentMethod.Name(), gCurrentStack.GetFrame(1).GetMethod.Name, System.Reflection.MethodBase.GetCurrentMethod.Module.Name, ex.Message, Application.ProductName)
Return False
End Try
Return True
End Function
#End Region
End Class
For testing, what happens if you don't close the stream?
ASKER
I tried that, but it still failed. I can't believe I've spent so much time trying to deal with images. Now looking at saving them in a DB, just to get around this problem :)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Your function is set as PRIVATE FUNCTION .... as Boolean
Well, the Boolean isn't going to hold the data you need, you need to return the image data.
Private Function .... as ImageData
And looking at your screen shots has me confused... I feel there were some changes made or we are not looking at the same code all the way through.
The file read function can't be boolean and pass the result you need. You need much more than a satisfactory reply with this, and if the imagedata comes back null, you know something failed.