I'm building a class library for various document types. One such type is an image which contains our custom business logic for dealing with images, including converting to PDF. I'm running into the problem described in many posts -- e.g. here and here -- where the System.Drawing.Image.Save
constructor is throwing a System.Runtime.InteropServices.ExternalException
exception with "A generic error occurred in GDI+".
The answers I've seen say that the input stream needs to be kept open throughout the lifetime of the Image
. I get that. The issue I have is that my class library doesn't control the input stream or even whether an input stream is used since I have two constructors. Here is some code:
public sealed class MyImage
{
private System.Drawing.Image _wrappedImage;
public MyImage(System.IO.Stream input)
{
_wrappedImage = System.Drawing.Image.FromStream(input);
}
public MyImage(System.Drawing.Image input)
{
_wrappedImage = input;
}
public MyPdf ConvertToPdf()
{
//no 'using' block because ms needs to be kept open due
// to third-party PDF conversion technology.
var ms = new System.IO.MemoryStream();
//System.Runtime.InteropServices.ExternalException occurs here:
//"A generic error occurred in GDI+"
_wrappedImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
return MyPdf.CreateFromImage(ms);
}
}
public sealed class MyPdf
{
internal static MyPdf CreateFromImage(System.IO.Stream input)
{
//implementation details not important.
return null;
}
}
My question is this: should I keep a copy of the input stream just to avoid the possibility that the client closes the stream before my image is saved? I.e., I could add this to my class:
private System.IO.Stream _streamCopy = new System.IO.MemoryStream();
and change the constructor to this:
public MyImage(System.IO.Stream input)
{
input.CopyTo(_streamCopy);
_wrappedImage = System.Drawing.Image.FromStream(_streamCopy);
}
This would of course add the overhead of copying the stream which is not ideal. Is there a better way to do it?