Question

I have some problems with this code that simply generate a graphical bitmap image (representing charts inside a PDF, but this is not important)

I have the following situation: in a class named PdfVulnerability I perform this statement

if (currentVuln.UrgencyRating > 0)
{
    img = Image.GetInstance(ChartHelper.GetPdfChart((int)currentVuln.UrgencyRating * 10), System.Drawing.Imaging.ImageFormat.Bmp);
    vulnerabilityDetailsTable.AddCell(new PdfPCell(img) { Border = PdfPCell.RIGHT_BORDER, BorderColor = new BaseColor(79, 129, 189), BorderWidth = 1, Padding = 5, MinimumHeight = 30, PaddingTop = 10 });
}

The value of currentVuln.UrgencyRating property is 7.5 so the debugger enter into the if body and try to perform this line:

img = Image.GetInstance(ChartHelper.GetPdfChart((int)currentVuln.UrgencyRating * 10), System.Drawing.Imaging.ImageFormat.Bmp);

So, using the debugger, I step into the ChartHelper.GetPdfChart((int)currentVuln.UrgencyRating * 10) execution.

Now the input paramether value is 70 (because it have cast to int the UrgencyRating value and and multiplied it by 10).

This is the body of the GetPdfChart() method that return a System.Drawing.Image object:

public static System.Drawing.Image GetPdfChart(int percentage)
    {
        if (percentage == 0)
        {
            return null;
        }

        int WIDTH = 130;
        int HEIGHT = 10;

        using (Bitmap bitmap = new Bitmap(WIDTH, HEIGHT))
        {
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                using (LinearGradientBrush brush = new LinearGradientBrush(new Rectangle(0, 0, WIDTH, HEIGHT), Color.LightGreen, Color.Red, LinearGradientMode.Horizontal))
                {
                    graphics.FillRectangle(brush, new Rectangle(0, 0, WIDTH, HEIGHT));

                    using (Bitmap target = new Bitmap(WIDTH * percentage / 100, HEIGHT))
                    {
                        Rectangle cropped = new Rectangle(0, 0, WIDTH, HEIGHT);

                        using (Graphics g = Graphics.FromImage(target))
                        {
                            g.DrawImage(bitmap, new Rectangle(0, 0, cropped.Width, cropped.Height), cropped, GraphicsUnit.Pixel);
                            //g.Save();
                            //String filename = Path.GetTempFileName() + ".png";
                            //target.Save(filename);
                            //return filename;

                            return bitmap;
                        }
                    }
                }
            }
        }
    }

This methow work fine and return a System.Drawing.Bitmap object to the caller that was:

img = Image.GetInstance(ChartHelper.GetPdfChart((int)currentVuln.UrgencyRating * 10), System.Drawing.Imaging.ImageFormat.Bmp);

And now my problem is that when come back and try to execute the previous operation it give me this exception that say: Parameter is not valid.

Was it helpful?

Solution

I think because you return disposed Bitmap object. The following code

using (Bitmap bitmap = new Bitmap(WIDTH, HEIGHT)) {
   // ... some code 
   return bitmap;
}

is equal to

try {
 Bitmap bitmap = new Bitmap(WIDTH, HEIGHT);
 return bitmap;
} finally {
   if (bitmap != null)
        bitmap.Dispose();    
}

An image is disposed right before return. A possible solution is to make a deep copy of created bitmap so that the old one is disposed:

using (Bitmap bitmap = new Bitmap(WIDTH, HEIGHT)) {
       // ... some code 
       return (Image)bitmap.Clone();
    }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top