Tony M
Tony M

Reputation: 329

GDI+ System.Runtime.InteropServices.ExternalException On Image resize and conversion

The ImageHandler class is responsible for converting the image to jpg and 60x60 size, then it converts it to Base64. The first Image is fine but when I try to proccess another image in the same run it crashes.

class ImageHandler
    {
        public static void convertToFormat(string filename)
        {
            var image = Image.FromFile(@filename);
            var bitmap = ResizeImage(image, Globals.ImageSize, Globals.ImageSize);
            bitmap.Save(Globals.PRED_PATH, ImageFormat.Jpeg);
        }

        public static Bitmap ResizeImage(Image image, int width, int height)
        {
             var destRect = new Rectangle(0, 0, width, height);
             var destImage = new Bitmap(width, height);

             destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

             using (var graphics = Graphics.FromImage(destImage))
             {
                 graphics.CompositingMode = CompositingMode.SourceCopy;
                 graphics.CompositingQuality = CompositingQuality.HighQuality;
                 graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                 graphics.SmoothingMode = SmoothingMode.HighQuality;
                 graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;

                 using (var wrapMode = new ImageAttributes())
                 {
                     wrapMode.SetWrapMode(WrapMode.TileFlipXY);
                     graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
                 }
             }
            return destImage;
        }

        public static string ConvertImageToBase64String()
        {
            Image image = Image.FromFile(Globals.PRED_PATH);
            var imageStream = new MemoryStream();
            image.Save(imageStream, ImageFormat.Jpeg);
            imageStream.Position = 0;
            var imageBytes = imageStream.ToArray();
            return Convert.ToBase64String(imageBytes);
        }
    }

Function Call:

ImageHandler.convertToFormat(FilePath);
string encodedImage = ImageHandler.ConvertImageToBase64String();

Upvotes: 0

Views: 57

Answers (1)

Marius
Marius

Reputation: 1679

As a quick fix you can add image.Dispose(); after image.Save(imageStream, ImageFormat.Jpeg); in the method ConvertImageToBase64String to make it work.

However I would recommend that you add using statements to convertToFormat and ConvertImageToBase64String to properly free the resources after use.

public static void convertToFormat(string filename)
{
    using (var image = Image.FromFile(@filename))
    {
        using (var bitmap = ResizeImage(image, Globals.ImageSize, Globals.ImageSize))
        {
            bitmap.Save(Globals.PRED_PATH, ImageFormat.Jpeg);
        }
    }
}

public static string ConvertImageToBase64String()
{
    using (var image = Image.FromFile(Globals.PRED_PATH))
    {
        using (var imageStream = new MemoryStream())
        {
            image.Save(imageStream, ImageFormat.Jpeg);
            imageStream.Position = 0;
            var imageBytes = imageStream.ToArray();
            return Convert.ToBase64String(imageBytes);
        }
    }
}

Upvotes: 1

Related Questions