I have a sub routine that I wrote in vb.net for asp.net to resize an image from a source location and write it to 3 seperate locations after creating some different sizes. It works well when I call the routine once after performing an image upload to the server.
But the kicker is that I also would like to use this as a batch image processor on a directory. So I wrote another routine that runs on a button click to call the resizeImage routine in a loop for all the images that need to be resized. When the button click
routine runs I get "A generic error occurred in GDI+". I put the code in a try catch to see if maybe it was one image or a particular type but it happens for all images. I have verified that the permissions are correct on the source and target image directories.
Here is a sample of what I get in my try catch:
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\tro651.jpg
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\tro760b.jpg
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\tro962.jpg
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\wmb500.jpg
Could not find:
d:\winhostssl01\hosting\shroomstr\upload\wr25.jpg
Could not find:
d:\winhostssl01\hosting\shroomstr\upload\WR30.jpg
0 Images already existed on the server
0 Images where imported to the server
202 Images could not be found
36 Errors occured
The could not find is ok due to that fact that not all the images are in the directory at the moment but I just can't seem to figure out what is causing the GDI+ error.
Here is the resizeImage routine that I have written:
Private Sub resizeImage(ByVal source As String, ByVal largeTarget As String, ByVal thumbTarget As String, ByVal origTarget As String)
Dim multiplier As Double = 5
Dim foundGoodSize As Boolean = False
Dim szLargeSize As Size = New Size(167, 198)
Dim szThumbSize As Size = New Size(83, 99)
Dim bmpNewBitmap As Bitmap
Dim bmpSource As Bitmap
Dim bmpThumb As Bitmap
Dim g As Graphics
bmpSource = Image.FromFile(source)
While Not foundGoodSize
If ((bmpSource.Width * multiplier <= szLargeSize.Width) And (bmpSource.Height * multiplier <= szLargeSize.Height)) Then
foundGoodSize = True
szLargeSize.Width = bmpSource.Width * multiplier
szLargeSize.Height = bmpSource.Height * multiplier
Else
multiplier -= 0.01
End If
End While
bmpNewBitmap = New Bitmap(szLargeSize.Width, szLargeSize.Height)
Here is the code I use to call it after the single image upload that works great:
Private Sub btnSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
Dim foundError As Boolean
lblInfo.Visible = False
uplProductImage.uploadResult = ""
If Page.IsValid Then
If uplProductImage.fileText <> "" Then
uplProductImage.upload(sender, e)
End If
Dim errorFound As Boolean
Dim myTarget As String
Dim source As String = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "upload\" & Path.GetFileName(uplProductImage.fileText)
If uplProductImage.fileText <> "" Then
If File.Exists(source) Then
resizeImage(source, largeTarget, thumbTarget, origTarget)
Else
lblInfo.Visible = True
lblInfo.Text = "You Must Upload The Image File Before You Can Submit The Product Information. Click The Upload File Button At The Bottom Of The Page."
errorFound = True
End If
End If
If Not errorFound Then
addProduct()
btnClear_Click(sender, e)
End If
End If
End Sub
Here is the code I use to call the resizeImage in the loop that is giving me the problem:
Private Sub btnImportImages_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportImages.Click
Dim cmdSelect As New SqlCommand("Select sku, manufacturer from products", conDb)
Dim ImportFileName As String
Dim dtResult As New DataTable
Dim myReader As SqlDataReader
Dim myRow As DataRow
Dim productCount As Integer
Dim imageExistOnServer As Integer
Dim imagesImported As Integer
Dim couldNotFind As Integer
Dim errorCount As Integer
conDb.Open()
myReader = cmdSelect.ExecuteReader
While myReader.Read
myRow = dtResult.NewRow
myRow.Item("sku") = myReader.Item("sku")
myRow.Item("manufacturer") = myReader.Item("manufacturer")
dtResult.Rows.Add(myRow)
productCount += 1
End While
conDb.Close()
lblImageImportResult.Text = productCount & " Products found in the database<br>"
For Each myRow In dtResult.Rows
ImportFileName = bulkImageDir & myRow.Item("sku") & ".jpg" 'myRow.Item("manufacturer") & "\" & myRow.Item("sku") & ".jpg"
Try
If Not File.Exists(largeTarget) Then
If File.Exists(ImportFileName) Then
resizeImage(ImportFileName, largeTarget, thumbTarget, origTarget)
imagesImported += 1
Else
lblImageImportResult.Text += "<br><br> Could not find:<br>" & ImportFileName
couldNotFind += 1
End If
Else
imageExistOnServer += 1
End If
Catch ex As Exception
lblImageImportResult.Text += "<br><br>Source: " & ex.Source & "<br>Message: " & ex.Message & "<br>" & ImportFileName
errorCount += 1
End Try
Next
lblImageImportResult.Text += "<br><br>" & imageExistOnServer & " Images already existed on the server<br>" & imagesImported & " Images where imported to the server<br>" & couldNotFind & " Images could not be found<br>" & errorCount & " Errors occured"
End Sub
Here is the Stack Trace from the error caused:
A generic error occurred in GDI+.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Alright, I finally found what was causing the error. It kind a dumb problem too. Oh well, sometimes I find it helps if you've been up coding for a while to just leave the problem and move on to something else for a bit. Anyway the problem was that I was passing
in the 3 targets to my imageResize subroutine after they were set for the single image upload routine. I was setting them in the page load like so.
The problem is that txtSku.Text is not set at this point leaving all the targets without a filename. Darn!
So here is the modified buttonClick routine that calls my resizeImage routine.
Private Sub btnImportImages_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportImages.Click
Dim cmdSelect As New SqlCommand("Select sku, manufacturer from products", conDb)
Dim ImportFileName As String
Dim dtResult As New DataTable
Dim myReader As SqlDataReader
Dim myRow As DataRow
Dim productCount As Integer
Dim imageExistOnServer As Integer
Dim imagesImported As Integer
Dim couldNotFind As Integer
Dim errorCount As Integer
Try
If Not File.Exists(largeTarget) Then
If File.Exists(ImportFileName) Then
resizeImage(ImportFileName, largeTarget, thumbTarget, origTarget)
imagesImported += 1
System.Threading.Thread.Sleep(10000)
Else
lblImageImportResult.Text += "<br><br> Could not find:<br>" & ImportFileName
couldNotFind += 1
End If
Else
imageExistOnServer += 1
End If
Catch ex As Exception
lblImageImportResult.Text += "<br><br>Source: " & ex.Source & "<br>Message: " & ex.Message & "<br>" & ImportFileName
errorCount += 1
End Try
Next
lblImageImportResult.Text += "<br><br>" & imageExistOnServer & " Images already existed on the server<br>" & imagesImported & " Images where imported to the server<br>" & couldNotFind & " Images could not be found<br>" & errorCount & " Errors occured"
End Sub
Notice the bold text above as it is what I had to add to solve the problem. I also moved the target assignments from the page load to their respective button click routine routine for the single image upload. So the moral behind the story is that when you read
oh about 15 forums saying that a "A generic error occurred in GDI+" is usually caused by invalid permssions or incorrect file paths look into that for just a little longer. Also, I would like to say thank you to anybody who has seen this post and tried to
solve my error even though that could have been difficult cause I never even posted the part of the code that was "essentially" causing the error.
John Vernon
Member
10 Points
2 Posts
A generic error occurred in GDI+
Jul 18, 2006 05:28 PM|LINK
Here is a sample of what I get in my try catch:
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\tro651.jpg
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\tro760b.jpg
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\tro962.jpg
Source: System.Drawing
Message: A generic error occurred in GDI+.
d:\winhostssl01\hosting\shroomstr\upload\wmb500.jpg
Could not find:
d:\winhostssl01\hosting\shroomstr\upload\wr25.jpg
Could not find:
d:\winhostssl01\hosting\shroomstr\upload\WR30.jpg
0 Images already existed on the server
0 Images where imported to the server
202 Images could not be found
36 Errors occured
The could not find is ok due to that fact that not all the images are in the directory at the moment but I just can't seem to figure out what is causing the GDI+ error.
Here is the resizeImage routine that I have written:
Private Sub resizeImage(ByVal source As String, ByVal largeTarget As String, ByVal thumbTarget As String, ByVal origTarget As String)
Dim multiplier As Double = 5
Dim foundGoodSize As Boolean = False
Dim szLargeSize As Size = New Size(167, 198)
Dim szThumbSize As Size = New Size(83, 99)
Dim bmpNewBitmap As Bitmap
Dim bmpSource As Bitmap
Dim bmpThumb As Bitmap
Dim g As Graphics
bmpSource = Image.FromFile(source)
While Not foundGoodSize
If ((bmpSource.Width * multiplier <= szLargeSize.Width) And (bmpSource.Height * multiplier <= szLargeSize.Height)) Then
foundGoodSize = True
szLargeSize.Width = bmpSource.Width * multiplier
szLargeSize.Height = bmpSource.Height * multiplier
Else
multiplier -= 0.01
End If
End While
bmpNewBitmap = New Bitmap(szLargeSize.Width, szLargeSize.Height)
g = Graphics.FromImage(bmpNewBitmap)
g.SmoothingMode = Drawing2D.SmoothingMode.HighQuality
g.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
g.PixelOffsetMode = Drawing2D.PixelOffsetMode.HighQuality
g.DrawImage(bmpSource, 0, 0, bmpNewBitmap.Width, bmpNewBitmap.Height)
szThumbSize.Width = szLargeSize.Width / 2
szThumbSize.Height = szLargeSize.Height / 2
bmpThumb = New Bitmap(bmpNewBitmap.GetThumbnailImage(szThumbSize.Width, szThumbSize.Height, Nothing, IntPtr.Zero))
bmpNewBitmap.SetResolution(72, 72)
bmpThumb.SetResolution(72, 72)
bmpSource.SetResolution(72, 72)
bmpNewBitmap.Save(largeTarget, Imaging.ImageFormat.Jpeg)
bmpThumb.Save(thumbTarget, Imaging.ImageFormat.Jpeg)
bmpSource.Save(origTarget, Imaging.ImageFormat.Jpeg)
bmpNewBitmap.Dispose()
bmpThumb.Dispose()
bmpSource.Dispose()
Here is the code I use to call it after the single image upload that works great:
Private Sub btnSubmit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSubmit.Click
Dim foundError As Boolean
lblInfo.Visible = False
uplProductImage.uploadResult = ""
If Page.IsValid Then
If uplProductImage.fileText <> "" Then
uplProductImage.upload(sender, e)
End If
Dim errorFound As Boolean
Dim myTarget As String
Dim source As String = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "upload\" & Path.GetFileName(uplProductImage.fileText)
If uplProductImage.fileText <> "" Then
If File.Exists(source) Then
resizeImage(source, largeTarget, thumbTarget, origTarget)
Else
lblInfo.Visible = True
lblInfo.Text = "You Must Upload The Image File Before You Can Submit The Product Information. Click The Upload File Button At The Bottom Of The Page."
errorFound = True
End If
End If
If Not errorFound Then
addProduct()
btnClear_Click(sender, e)
End If
End If
End Sub
Here is the code I use to call the resizeImage in the loop that is giving me the problem:
Private Sub btnImportImages_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportImages.Click
Dim cmdSelect As New SqlCommand("Select sku, manufacturer from products", conDb)
Dim ImportFileName As String
Dim dtResult As New DataTable
Dim myReader As SqlDataReader
Dim myRow As DataRow
Dim productCount As Integer
Dim imageExistOnServer As Integer
Dim imagesImported As Integer
Dim couldNotFind As Integer
Dim errorCount As Integer
dtResult.Columns.Add("sku")
dtResult.Columns.Add("manufacturer")
conDb.Open()
myReader = cmdSelect.ExecuteReader
While myReader.Read
myRow = dtResult.NewRow
myRow.Item("sku") = myReader.Item("sku")
myRow.Item("manufacturer") = myReader.Item("manufacturer")
dtResult.Rows.Add(myRow)
productCount += 1
End While
conDb.Close()
lblImageImportResult.Text = productCount & " Products found in the database<br>"
For Each myRow In dtResult.Rows
ImportFileName = bulkImageDir & myRow.Item("sku") & ".jpg" 'myRow.Item("manufacturer") & "\" & myRow.Item("sku") & ".jpg"
Try
If Not File.Exists(largeTarget) Then
If File.Exists(ImportFileName) Then
resizeImage(ImportFileName, largeTarget, thumbTarget, origTarget)
imagesImported += 1
Else
lblImageImportResult.Text += "<br><br> Could not find:<br>" & ImportFileName
couldNotFind += 1
End If
Else
imageExistOnServer += 1
End If
Catch ex As Exception
lblImageImportResult.Text += "<br><br>Source: " & ex.Source & "<br>Message: " & ex.Message & "<br>" & ImportFileName
errorCount += 1
End Try
Next
lblImageImportResult.Text += "<br><br>" & imageExistOnServer & " Images already existed on the server<br>" & imagesImported & " Images where imported to the server<br>" & couldNotFind & " Images could not be found<br>" & errorCount & " Errors occured"
End Sub
Here is the Stack Trace from the error caused:
A generic error occurred in GDI+.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[ExternalException (0x80004005): A generic error occurred in GDI+.]
System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams) +579
System.Drawing.Image.Save(String filename, ImageFormat format) +59
enternetshop.dbManager1.resizeImage(String source, String largeTarget, String thumbTarget, String origTarget)
enternetshop.dbManager1.btnImportImages_Click(Object sender, EventArgs e)
System.Web.UI.WebControls.Button.OnClick(EventArgs e) +108
System.Web.UI.WebControls.Button.System.Web.UI.IPostBackEventHandler.RaisePostBackEvent(String eventArgument) +57
System.Web.UI.Page.RaisePostBackEvent(IPostBackEventHandler sourceControl, String eventArgument) +18
System.Web.UI.Page.RaisePostBackEvent(NameValueCollection postData) +33
System.Web.UI.Page.ProcessRequestMain() +1292
Version Information: Microsoft .NET Framework Version:1.1.4322.2300; ASP.NET Version:1.1.4322.2300
If somebody could please look at this and see if I am overlooking something it would be greatly appreciated.
John Vernon
Member
10 Points
2 Posts
Re: A generic error occurred in GDI+
Jul 21, 2006 04:06 AM|LINK
largeTarget = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "images\products\large\" & txtSku.Text.ToLower & Path.GetExtension(uplProductImage.fileText)
thumbTarget = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "images\products\thumb\" & txtSku.Text.ToLower & Path.GetExtension(uplProductImage.fileText)
origTarget = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "images\products\orig\" & txtSku.Text.ToLower & Path.GetExtension(uplProductImage.fileText)
The problem is that txtSku.Text is not set at this point leaving all the targets without a filename. Darn!
So here is the modified buttonClick routine that calls my resizeImage routine.
Private Sub btnImportImages_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnImportImages.Click
Dim cmdSelect As New SqlCommand("Select sku, manufacturer from products", conDb)
Dim ImportFileName As String
Dim dtResult As New DataTable
Dim myReader As SqlDataReader
Dim myRow As DataRow
Dim productCount As Integer
Dim imageExistOnServer As Integer
Dim imagesImported As Integer
Dim couldNotFind As Integer
Dim errorCount As Integer
dtResult.Columns.Add("sku")
dtResult.Columns.Add("manufacturer")
conDb.Open()
myReader = cmdSelect.ExecuteReader
While myReader.Read
myRow = dtResult.NewRow
myRow.Item("sku") = myReader.Item("sku")
myRow.Item("manufacturer") = myReader.Item("manufacturer")
dtResult.Rows.Add(myRow)
productCount += 1
End While
conDb.Close()
lblImageImportResult.Text = productCount & " Products found in the database<br>"
For Each myRow In dtResult.Rows
ImportFileName = bulkImageDir & myRow.Item("sku") & ".jpg" 'myRow.Item("manufacturer") & "\" & myRow.Item("sku") & ".jpg"
largeTarget = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "images\products\large\" & myRow.Item("sku") & ".jpg"
thumbTarget = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "images\products\thumb\" & myRow.Item("sku") & ".jpg"
origTarget = HttpContext.Current.Server.MapPath(Request.ApplicationPath) & "images\products\orig\" & myRow.Item("sku") & ".jpg"
Try
If Not File.Exists(largeTarget) Then
If File.Exists(ImportFileName) Then
resizeImage(ImportFileName, largeTarget, thumbTarget, origTarget)
imagesImported += 1
System.Threading.Thread.Sleep(10000)
Else
lblImageImportResult.Text += "<br><br> Could not find:<br>" & ImportFileName
couldNotFind += 1
End If
Else
imageExistOnServer += 1
End If
Catch ex As Exception
lblImageImportResult.Text += "<br><br>Source: " & ex.Source & "<br>Message: " & ex.Message & "<br>" & ImportFileName
errorCount += 1
End Try
Next
lblImageImportResult.Text += "<br><br>" & imageExistOnServer & " Images already existed on the server<br>" & imagesImported & " Images where imported to the server<br>" & couldNotFind & " Images could not be found<br>" & errorCount & " Errors occured"
End Sub
Notice the bold text above as it is what I had to add to solve the problem. I also moved the target assignments from the page load to their respective button click routine routine for the single image upload. So the moral behind the story is that when you read oh about 15 forums saying that a "A generic error occurred in GDI+" is usually caused by invalid permssions or incorrect file paths look into that for just a little longer. Also, I would like to say thank you to anybody who has seen this post and tried to solve my error even though that could have been difficult cause I never even posted the part of the code that was "essentially" causing the error.
bluekiwi
Participant
1461 Points
316 Posts
Re: A generic error occurred in GDI+
Aug 17, 2006 01:47 PM|LINK
1. The VS 2005 and IIS server can't write to certain folders, no matter what account is given permission.
2. Turning off the "readonly" attibute on the folder doesn't help.
I get a resized picture, but some are out of focus and pixellated.
And there is a bug? http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=631868&SiteID=1