Hello All
I got the following exception while a call of web service method to retrieve image data after 3 or 4 hours using the application. I have classic asmx web service hosted on the server(developed in VS2012 Framework 4.0, published as 32 bit application) the configuration of the server where this webservice hosted is windows server 2008, IIS version : 7.0, 24 gb RAM,
and client application running on the client machine (developed in VS 2012, Framework 4.0, 32 bit application, the configuration of the client workstation where this issue occurred is OS: windows 7, 8 GB RAM ). once I got this exception I need to close the application otherwise I got the same exception all over the application where image data need to retrieve from webservice. Once I restart the application it works fine for again 2 to 3 hours without any issue with same image data. I don't know what exactly the issue here.
Exception: Exception of type 'System.OutOfMemoryException' was thrown.
Source: mscorlib Target: Byte[] FromBase64String(System.String)
Stack Trace: at System.Convert.FromBase64String(String s) at System.Data.Common.ObjectStorage.ConvertXmlToObject(String s) at System.Data.XmlDataLoader.LoadColumn(DataColumn column, Object[] foundColumns) at System.Data.XmlDataLoader.LoadTable(DataTable table, Boolean isNested) at System.Data.XmlDataLoader.LoadData(XmlReader reader) at System.Data.DataSet.ReadXmlDiffgram(XmlReader reader) at System.Data.DataSet.ReadXml(XmlReader reader, XmlReadMode mode, Boolean denyResolving) at System.Data.DataSet.ReadXmlSerializable(XmlReader reader) at System.Data.DataSet.System.Xml.Serialization.IXmlSerializable.ReadXml(XmlReader reader) at System.Xml.Serialization.XmlSerializationReader.ReadSerializable(IXmlSerializable serializable, Boolean wrappedAny) at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderXRMSGeneral.Read478_getImagesDataResponse() at Microsoft.Xml.Serialization.GeneratedAssembly.ArrayOfObjectSerializer992.Deserialize(XmlSerializationReader reader) at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle, XmlDeserializationEvents events) at System.Web.Services.Protocols.SoapHttpClientProtocol.ReadResponse(SoapClientMessage message, WebResponse response, Stream responseStream, Boolean asyncCall) at System.Web.Services.Protocols.SoapHttpClientProtocol.Invoke(String methodName, Object[] parameters) at .........
My web service code is below. I am compressing the image if the size of the image is greater than 480,600
<WebMethod()> _
Public Function getImagesData(ByVal ID As Integer) As DataSet
Try
Dim ds As DataSet = ....// Retrive data from database here
UpdateImage(ds, "Table", "Image")
Return ds
Catch ex As Exception
Throw LogExcption(ex)
Return Nothing
End Try
End Function
Public Sub UpdateImage(ByRef objDS As DataSet, ByVal TableName As String, ByVal columnName As String)
If objDS.Tables(TableName).Rows.Count > 0 Then
For intCnt As Integer = 0 To objDS.Tables(TableName).Rows.Count - 1
If Not IsDBNull(objDS.Tables(TableName).Rows(intCnt)(columnName)) Then
Try
Dim OldImage As Image = Nothing
Dim NewImage As Image = Nothing
OldImage = Byte2Image(CType(objDS.Tables(TableName).Rows(intCnt)(columnName), Byte()))
Dim RenderSize As System.Drawing.Size
RenderSize.Width = 480
RenderSize.Height = 600
If OldImage.Width > 480 AndAlso OldImage.Height > 600 Then
NewImage = CompressImage(OldImage, RenderSize)
Else
NewImage = OldImage
End If
Dim ms = New System.IO.MemoryStream()
NewImage.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg) ' Use appropriate format here
Dim bytes As Byte()
bytes = ms.ToArray()
objDS.Tables(TableName).Rows(intCnt)(columnName) = bytes
Catch ex As Exception
End Try
End If
Next
End If
End Sub
Public Shared Function CompressImage(ByRef original As Image, ByVal renderSize As Size) As Image
Return CompressImage(original, renderSize, System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear)
End Function
Public Shared Function CompressImage(original As Image, renderSize As Size, mode As System.Drawing.Drawing2D.InterpolationMode) As Image
If (((original Is Nothing) OrElse (renderSize.Width = 0)) OrElse ((renderSize.Height = 0) OrElse (renderSize.Width >= original.Width))) OrElse (renderSize.Height >= original.Height) Then
Return original
End If
Dim aspectRation As Double = original.Width / original.Height
Dim minDim As Integer = Math.Min(renderSize.Width, renderSize.Height)
Dim scaleFactor As Double = 0.0
If aspectRation >= 1.0 Then
scaleFactor = original.Width / minDim
Else
scaleFactor = original.Height / minDim
End If
If (1.0 / scaleFactor) < 0.01 Then
Throw New Exception("CompressImage size must be at least 1% of the original")
End If
Dim outWidth As Integer = CInt(Math.Truncate(CDbl(original.Width) / scaleFactor))
Dim outHeight As Integer = CInt(Math.Truncate(CDbl(original.Height) / scaleFactor))
Dim outImage As New Bitmap(outWidth, outHeight)
Using g As Graphics = Graphics.FromImage(outImage)
g.InterpolationMode = mode
g.DrawImage(original, New Rectangle(0, 0, outImage.Width, outImage.Height), 0, 0, original.Width, original.Height, _
GraphicsUnit.Pixel)
End Using
Return outImage
End Function
Public Function Byte2Image(ByVal ByteArr() As Byte) As Image
Try
If ByteArr.Length > 0 Then
Dim image As Image
Using ms As New System.IO.MemoryStream(ByteArr)
image = System.Drawing.Image.FromStream(ms)
End Using
Return image
End If
Catch ex As Exception
Return Nothing
End Try
End Function