A generic error occurred in GDI+.

Oct 18, 2014 at 11:57 AM
Hi,

Platform ASP.NET, C#.

System.Runtime.InteropServices.ExternalException was caught
HResult=-2147467259
Message=A generic error occurred in GDI+.
Source=System.Drawing
ErrorCode=-2147467259
StackTrace:
   at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
   at System.Drawing.Image.Save(String filename, ImageFormat format)
   at System.Drawing.Image.Save(String filename)
   at PreTwitters.helper.Twitter.Tweet(String authorid, String poemJSON) in C:\Projects\Twitter\PreTwitters\PreTwitters\helper\Twitter.cs:line 33

InnerException:

This error is not related to the HTML Rendered. It happens when I use Image.Save to save the Image into a file.
I have checked everything the filename, directory..etc, everything is OK!

Actually, I have implemented and added this class "Converter" into the HTML Rendered in order to be able to use the "RenderToImage" function to renders the HTML into a new image of unknown size.
    public static class Converter
    {
        public static Image ToImage(string html)
        {
            Image result = HtmlRender.RenderToImage(html);
            return result;

        }
    }
And here the Coordinator class
    public class Coordinator
    {
        public static Image ToImage(string html)
        {
            Image result = TheArtOfDev.HtmlRenderer.WinForms.Converter.ToImage(html);
            return result;
        }
    }
And Finally here is the code to save the image into a file
        public static string Tweet(string authorid, string poemJSON)
        {
            
            string PhysicalPath = HttpContext.Current.Server.MapPath(".") + "\\authors\\" + authorid;
            string FileName = Poem.Base62Random() + ".jpg";
            string FilePathAndName = PhysicalPath + FileName;
            
            Poem poem = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Poem>(poemJSON);

            string html = poem.GetHTML();



            try
            {

                Image ToBeSaved = Coordinator.ToImage(html);
                ToBeSaved.Save(FilePathAndName);//, System.Drawing.Imaging.ImageFormat.Jpeg);

                /*
                I have tried the below solutions:
                1- Save it with specifing the image format
                ToBeSaved.Save(FilePathAndName, System.Drawing.Imaging.ImageFormat.Jpeg);
                2- Save it into a new image to mak sure we are able to access a free image. 
                Bitmap go = new Bitmap(ToBeSaved);
                go.Save(FilePathAndName, System.Drawing.Imaging.ImageFormat.Jpeg);
                */
            }
            catch (Exception ex)
            {
                FilePathAndName = null;
            }

            return "http://localhost:62915/authors/123/" + FileName;
        }
I appreciate your help.
Developer
Oct 18, 2014 at 12:56 PM
make sure you have permission to write to the required path on the disk "PhysicalPath", try "File.WriteAllText(FilePathAndName,"test")" to see that it works.

what is the purpose of "Coordinator" and "Converter" classes? It looks like direct delegate to "HtmlRender.RenderToImage" without any additional logic.
Oct 18, 2014 at 1:23 PM
Thank you for your response.

I forgot to say: a zero size file is created each time I use Image.Save ! In addition, I have the same error when trying to save the image to stream!!
So, there is no permission issue.

I have spent a hours googling and come up with two reasons:
1-permission (might be solved by giving write permission to a user).
2- image object issue (might be solved by creating a new image, then use the new image to save your image to a file). The idea here is that the first image sometimes for unknown reason is inaccessible!!!

However, none of these solutions solved my issue.

Do you have any idea or advices please?

About The Coordinator class, You are right. I was too lazy to delete it :) .
Developer
Oct 18, 2014 at 2:22 PM
try saving as png, no need to to copy "ToBeSaved" image to "go"
Oct 18, 2014 at 6:10 PM
Edited Oct 18, 2014 at 6:11 PM
I have found a likely cause!

I hope I am wrong. When rendering HTML under some conditions this might happens.
Please try to render this HTML (Pass the HTML directly from your code to RenderToImage, do not use input component) you expect to face this error.
<html dir='rtl'>
                            <head>
                                <title></title>
                                <style type='text/css'>
                                
        body
        {
            background-color: #FF0000 ; background-gradient: #FFFFFF; background-gradient-angle: 60; corner-radius: 10px; margin: 0; padding: 2px;
        }
        
        .WhitePanel { background-color:white; corner-radius:10px; padding:15px; }

        .Part1
        {
            clear: right;
            display: block;
            margin: 0px;
            font-size: large;
            font-color: #9ACD32;
        }
        .Part2
        {
            clear: right;
            display: block;
            float: left;
            width: 75%;
            margin-right: 3px;
            margin-top: 0px;
            white-space: nowrap;
            font-size: large;
            font-color: #9ACD32;
        }
                                </style>
                            </head>
                            <body>
                            <blockquote id='blkQsead' class='WhitePanel'>
                                <p><span class='Part1'>Test</span><span class='Part2'>Test</span><br></p>
                            </blockquote>
                                <hr/>
                            <blockquote>
                              <span>Test HTML Rendered</span>
                            </blockquote>
                            </body>
                        </html>
Now remove the first blockquote tag from the HTML code
<blockquote id='blkQsead' class='WhitePanel'>
                                <p><span class='Part1'>Test</span><span class='Part2'>Test</span><br></p>
                            </blockquote>
To be
<html dir='rtl'>
                            <head>
                                <title></title>
                                <style type='text/css'>
                                
        body
        {
            background-color: #FF0000 ; background-gradient:#FFFFFF ; background-gradient-angle: 60; corner-radius: 10px; margin: 0; padding: 2px;
        }
        
        .WhitePanel { background-color:white; corner-radius:10px; padding:15px; }

        .Part1
        {
            clear: right;
            display: block;
            margin: 0px;
            font-size: large;
            font-color: #9ACD32;
        }
        .Part2
        {
            clear: right;
            display: block;
            float: left;
            width: 75%;
            margin-right: 3px;
            margin-top: 0px;
            white-space: nowrap;
            font-size: large;
            font-color: #9ACD32;
        }
                                </style>
                            </head>
                            <body>
                                <hr/>
                            <blockquote>
                              <span>Test HTML Rendered</span>
                            </blockquote>
                            </body>
                        </html>
Try to render the new HTML code.

When I did this the first one result in generic error. However, the error has gone After removing the tag!

Might the Tab space causes this problem! Maybe!
Oct 18, 2014 at 6:32 PM
For more accurate.

This issue can be clearly seen when you use more than one span element in the same block and each span has a different class name.
Developer
Nov 1, 2014 at 4:37 PM
sorry for the late reply, didn't have time to check it.
found the issue, the html snipped you are using has relative width of 75%, in this case the html layout tries to take as much space as possible and because image rendering, unlike control, has no width limit it tries to create image that is too large, resulting in GDI+ error.
the simplest solution is to specify maxWidth as the second parameter to RenderToImage.
I will also add a safeguard in code so the final image will be limited to 4096, unless specific max width limit is provided.
Nov 7, 2014 at 8:28 AM
Thank you. I will try send you a complete example of this issue.