locked
A generic error occurred in GDI+ RRS feed

  • Question

  • User-1258081508 posted
    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)

            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.
    Tuesday, July 18, 2006 1:28 PM

All replies

  • User-1258081508 posted
    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.

    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.
    Friday, July 21, 2006 12:06 AM
  • User-1143650407 posted
    I have read most of the posts on this topic and on my machine:

    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
    Thursday, August 17, 2006 9:47 AM