We're sorry Aspose doesn't work properply without JavaScript enabled.

Free Support Forum - aspose.com

GDI+ exception on Shape.ImageData.SetImage(Image)

Our code works for an indeterminate period of time, but after that time, the call always throws an exception until the server is rebooted. It is not resolved by restarting the IIS website, its app pool, or restarting IIS.

The exception is:

System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+.
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)

The code is as follows:

Document template;

using (var file = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
    template = new Document(file);
}

var document = new Document();
var builder = new DocumentBuilder(document);
builder.Document.RemoveAllChildren();
builder.Document.AppendDocument(template, ImportFormatMode.KeepSourceFormatting);
builder.MoveToSection(nextSectionIndex);
var nodes = builder.CurrentSection.GetChildNodes(NodeType.Shape, true).Cast<Shape>().ToList();

...

Image img = new Bitmap(300, 300);
using (var fontFamily = new FontFamily("Arial"))
using (var font = new System.Drawing.Font(fontFamily, 13))
using (var textBrush = new SolidBrush(Color.LightGray))
using (var drawing = Graphics.FromImage(img))
{
    drawing.Clear(Color.White);
    drawing.TranslateTransform(-190.0F, 100.0F);
    drawing.RotateTransform(-45.0F);
    drawing.DrawString(text, font, textBrush, new RectangleF(0, 0, 500, 500));
    drawing.Save();
}

...

var node = nodeList.Single(n => n.Name.Contains("Watermark");
((Shape)node.FirstParagraph.FirstChild).ImageData.SetImage(nodeImage);

Is the call to SetImage() creating a temporary file which is deleted upon reboot?

@pmarkham No, Aspose.Words does not create any temporary files when ImageData.SetImage method is called.
In your case, as I can see, you use ImageData.SetImage overload which accepts System.Drawing.Image, in this case, Aspose.Words saves the image to stream and internally calls ImageData.SetImage overload that accepts stream. So to isolate the problem you can save your image into stream or byte array in your code and use the appropriate overload of ImageData.SetImage method.
Also, as I can guess from your code, you are replacing watermark in the document. In this case, you can try using built-in Aspose.Words API to do this using Watermark class. In your case, since you are inserting text watermark, you can use Watermark.SetText method. In this case watermark will be inserted as a WordArt object and System.Drawing (GDI+) will not be involved at all.

Thanks. I’ll try saving the image to a stream and passing that to ImageData.SetImage.

As no files are involved, can you think of any other reason a generic GDI+ exception would occur, particularly one that’s only resolved by a reboot?

The watermark we use is only on a particular part of the document, and is repeating text, so the Document.Watermark doesn’t look suitable. We also add a barcode image (generated using ZXing.Net) to the document in the same way - I’ll also save that to a stream before adding to the document with ImageData.SetImage.

@pmarkham

This looks like permission issue. But the method definitely does not save any temporary files. Even if it does, the exception occurred every time you call it. I suspect it is some kind of glitch in GDI+. Is it possible to create a simple application that will allow us to reproduce the problem? This would allow us to investigate the issue.

That’s what I thought - or a disk/quota full. Those are the only explanations for the exception that I’ve found.

Unfortunately I can’t create a simple application that reproduces the problem - the existing application runs constantly, but has only failed sporadically.

@pmarkham Thank you for additional information. I hope saving to a stream will allow you to resolve or at least isolate the issue on your side. Please let us know if you manage to catch what causes the issue on your side.

We’ve had the issue again, using Shape.ImageData.SetImage(stream).

The logged exception/call stack is:
System.Runtime.InteropServices.ExternalException (0x80004005): A generic error occurred in GDI+. at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) at
.(MemoryStream ) at
. (Byte[] ) at .(Byte[] ) at .(Byte[] )

@pmarkham Does the exception occur with some specific image? Or it occurs randomly again? What is the original image format that the stream contains? Can you convert the image in the scream to PNG first (for testing purposes)? I am doubt the problem is in Aspose.Words, I prety sure, it is in GDI+.

The exception occurs using an image generated by the previously-posted code, but now converted to a stream before calling SetImage():

using (var stream = new MemoryStream())
{
    using (var img = new Bitmap(300, 300))
    {
        using (var fontFamily = new FontFamily("Arial"))
        using (var font = new System.Drawing.Font(fontFamily, 13))
        using (var textBrush = new SolidBrush(Color.LightGray))
        using (var drawing = Graphics.FromImage(img))
        {
            drawing.Clear(Color.White);
            drawing.TranslateTransform(-190.0F, 100.0F);
            drawing.RotateTransform(-45.0F);
            drawing.DrawString(text, font, textBrush, new RectangleF(0, 0, 500, 500));
            drawing.Save();
        }

        img.Save(stream, ImageFormat.Bmp);
    }

    ((Shape)node.FirstParagraph.FirstChild).ImageData.SetImage(stream);
}

At a seemingly random point in time (the latest being 14/05/2022 01:29:32), the exception occurs, and continues to occur until the computer is rebooted. Restarting the application does not resolve the issue.

@pmarkham Thank you for additional information. In your code you save the image as BMP to stream. Aspose.Words internally converts BMP to PNG (using GDI+) that, most likely, causes the problem. Could you please try saving your image directly to PNG, so Aspose.Words does not need to perform the conversion.

PS: BMP are converted to PNG because sometimes MS Word fails on some DIB formats (32 bit color for example). To keep document stable PNG is the default image format.

Thanks, I’ll try that.

1 Like