Finding Memory Leak?

Magick.NET is an object-oriented C# interface to ImageMagick. Use this forum to discuss, make suggestions about, or report bugs concerning Magick.NET
Post Reply
GlennIM
Posts: 24
Joined: 2018-07-22T22:22:12-07:00
Authentication code: 1152

Finding Memory Leak?

Post by GlennIM »

If anyone is good at finding memory leaks, maybe they can point me in the right direction why the method below is causing memory to not be released when called multiple times in the same program. Calling it a few times it is OK, but when done many times over, the application crashes "Out-Of-Memory". Or if someone know a good way to find the memory leak, I'd love to hear about that as these things are really hard to debug.

Code: Select all

private void ApplyImageTransformationClean(string imgURL, string FontFamily, string headingStr, string randomHeadlineStr, string imgFileName)
        {
            MagickImage imageresult;
            MagickImage modimage;
            Color backgroundColorForTopBottom;
            Color borderColor;
            int ExtentHeight = 70;
            MagickImage mask = null;
            MagickImageCollection images;
            IMagickImage result;
            MagickImage branding;
            MagickImage topheading;
            MagickImage heading;
            MagickImage randomHeadline;
            ImageMagick.Drawables drawables;

            using (var image = new MagickImage(imgURL))
            {
                // passing the FontFamily parameter is used for testing fonts to see how they look
                // if nothing is passed in a random font will be found and used
                if (FontFamily == "")
                {
                    FontFamily = GetRandomFontFamily();
                }

                try
                {
                    KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));

                    // START BRANDING/LABEL CODE
                    // Start with a collection because multiple images will be combined.
                    using (images = new MagickImageCollection())
                    {
                        int widthOfImage = GetProperFontSize(image);

                        backgroundColorForTopBottom = GetRandomizedKnownColor();

                        var topheaderSnippetreadSettings = new MagickReadSettings()
                        {
                            BackgroundColor = backgroundColorForTopBottom,

                            FontFamily = FontFamily, // -font Helvetica-Condensed-Light

                            Width = image.Width - 190,
                            FillColor = IdealTextColor(backgroundColorForTopBottom),
                            FontWeight = FontWeight.Bold
                        };

                        var headerSnippetreadSettings = new MagickReadSettings()
                        {
                            BackgroundColor = backgroundColorForTopBottom,

                            FontFamily = FontFamily, // -font Helvetica-Condensed-Light

                            Width = image.Width - 60,
                            FillColor = IdealTextColor(backgroundColorForTopBottom),
                            FontWeight = FontWeight.Bold
                        };

                        // This will make the background of the label Khaki.
                        var readSettings = new MagickReadSettings()
                        {
                            BackgroundColor = backgroundColorForTopBottom,
                            FontFamily = "Helvetica-Condensed-Light", // -font Helvetica-Condensed-Light
                            FontPointsize = widthOfImage - 10, // -pointsize 26
                            FillColor = IdealTextColor(backgroundColorForTopBottom),
                            FontWeight = FontWeight.Bold
                        };

                        // Create the label image.
                        branding = new MagickImage("label:" + moneySiteDomainName, readSettings);

                        branding.Extent(image.Width, ExtentHeight, Gravity.Center); // height was 100

                        // Create the label image.
                        topheading = new MagickImage("label:" + headingStr, topheaderSnippetreadSettings);
                        heading = new MagickImage("label:" + headingStr, headerSnippetreadSettings);
                        randomHeadline = new MagickImage("label:" + randomHeadlineStr, headerSnippetreadSettings);

                        topheading.Extent(image.Width, ExtentHeight, Gravity.Center); // height was 100
                        heading.Extent(image.Width, ExtentHeight, Gravity.Center); // height was 100
                        randomHeadline.Extent(image.Width, ExtentHeight, Gravity.Center); // height was 100

                        // Bottom
                        if (currentTemplate == Templates.Image_Branding)
                        {
                            images.Add(image);
                            images.Add(branding);
                        }

                        // Top & Bottom
                        if (currentTemplate == Templates.Heading_Image_Branding)
                        {
                            images.Add(topheading);
                            images.Add(image);
                            images.Add(branding);
                        }

                        // Bottom with 2 Snippets
                        if (currentTemplate == Templates.Image_Heading_Branding)
                        {
                            images.Add(image);
                            images.Add(heading);
                            images.Add(branding);
                        }

                        if (currentTemplate == Templates.Heading_Image_RandomHeadline_Branding)
                        {
                            images.Add(topheading);
                            images.Add(image);
                            images.Add(randomHeadline);
                            images.Add(branding);
                        }

                        // Append the images to create the output image.
                        using (result = images.AppendVertically())
                        {
                            imageresult = new MagickImage(result);

                            // imageresult gets disposed of in the rounding code below, so need to write the imageresult to a new image
                            modimage = new MagickImage(imageresult);
                        }


                    } // using (images = new MagickImageCollection())

                    // END BRANDING/LABEL CODE

                    // using (var image = new MagickImage(imgURL))
                    if (specialEffects == SpecialEffects.RoundedCorners || specialEffects == SpecialEffects.RoundedCorners_ColoredBorders || specialEffects == SpecialEffects.RoundedCorners_Frames3D || specialEffects == SpecialEffects.RoundedCorners_Frames3D_Swirl || specialEffects == SpecialEffects.RoundedCorners_Raise)
                    {
                        using (imageresult)
                        {
                            using (mask = new MagickImage(MagickColors.White, imageresult.Width, imageresult.Height))
                            {
                                var size = 150;

                                drawables = new ImageMagick.Drawables()
                                    .FillColor(MagickColors.Black)
                                    .StrokeColor(MagickColors.Black)
                                    .Polygon(new PointD(0, 0), new PointD(0, size), new PointD(size, 0))
                                    .Polygon(new PointD(mask.Width, 0), new PointD(mask.Width, size), new PointD(mask.Width - size, 0))
                                    .Polygon(new PointD(0, mask.Height), new PointD(0, mask.Height - size), new PointD(size, mask.Height))
                                    .Polygon(new PointD(mask.Width, mask.Height), new PointD(mask.Width, mask.Height - size), new PointD(mask.Width - size, mask.Height))
                                    .FillColor(MagickColors.White)
                                    .StrokeColor(MagickColors.White)
                                    .Circle(size, size, size, 0)
                                    .Circle(mask.Width - size, size, mask.Width - size, 0)
                                    .Circle(size, mask.Height - size, 0, mask.Height - size)
                                    .Circle(mask.Width - size, mask.Height - size, mask.Width - size, mask.Height)
                                    // .BorderColor(MagickColors.Red)
                                    .Draw(mask);  

                                // This copies the pixels that were already transparent on the mask.
                                using (var imageAlpha = imageresult.Clone())
                                {
                                    imageAlpha.Alpha(AlphaOption.Extract);
                                    imageAlpha.Opaque(MagickColors.White, MagickColors.None);
                                    mask.Composite(imageAlpha, CompositeOperator.Over);
                                }

                                mask.HasAlpha = false;
                                imageresult.HasAlpha = false;
                                imageresult.Composite(mask, CompositeOperator.CopyAlpha);

                                // imageresult gets disposed of so need to write the imageresult to a new image
                                modimage = new MagickImage(imageresult);
                            }
                        }
                    }

                    // Add colored border to the image
                    if (specialEffects == SpecialEffects.RoundedCorners_ColoredBorders)
                    {
                        borderColor = GetBorderColor(); // get a random reddish color

                        modimage.BorderColor = borderColor;
                        modimage.Border(1);

                        // apply a 3D frame even if the border color is a reddish color
                        modimage = Create3DFramedBorder(modimage);
                    }
                    else if (specialEffects == SpecialEffects.RoundedCorners_Frames3D)
                    {
                        modimage.BorderColor = MagickColors.White;
                        modimage.Border(1);

                        // apply a 3D frame
                        modimage = Create3DFramedBorder(modimage);
                    }
                    else if (specialEffects == SpecialEffects.RoundedCorners_Frames3D_Swirl)
                    {
                        modimage.BorderColor = MagickColors.White;
                        modimage.Border(1);

                        // apply a 3D frame
                        modimage = Create3DFramedBorder(modimage);

                        modimage.Swirl(25.0);
                    }
                    else if (specialEffects == SpecialEffects.RoundedCorners_Raise)
                    {
                        modimage.BorderColor = MagickColors.White;
                        modimage.Border(1);

                        // modimage = Create3DFramedBorder(modimage);

                        modimage.Raise(25);
                    }
                    else if (specialEffects == SpecialEffects.RoundedCorners)
                    {
                        modimage.BorderColor = MagickColors.White;
                        modimage.Border(1);
                    }

                    // write the image to the appropriate directory
                    modimage.Write(pinImagesCSVLocationPathLocal + "\\" + imgFileName);

                    // also write the image to the fixed path under output so they all can be viewed
                    modimage.Write(allPinImagesLocationPathLocal + "\\" + imgFileName);

                    FileInfo imageMod = new FileInfo(pinImagesCSVLocationPathLocal + "\\" + imgFileName);

                    optimizer.Compress(imageMod);

                    displayStatus("Image Created and Compressed: " + imgFileName);

                    // show the image in the picture box
                    pinImagePB.Image = Image.FromFile(imageMod.FullName);
                    // resize the image to fit the PictureBox size
                    pinImagePB.SizeMode = PictureBoxSizeMode.StretchImage;
                    pinImagePB.Refresh();

                    try
                    {
                        image.Dispose();
                        images.Dispose();
                        branding.Dispose();
                        topheading.Dispose();
                        heading.Dispose();
                        randomHeadline.Dispose();
                        mask.Dispose();
                        imageresult.Dispose();
                        modimage.Dispose();
                        result.Dispose();
                        //pinImagePB.Dispose();

                        displayStatus("In applyImageTransformationClean(): Disposed All Image Objects");
                    }
                    catch (Exception disposeEsc)
                    {
                        displayStatus("In applyImageTransformationClean(): Failed To Dispose Image Objects: " + disposeEsc.Message);
                        GC.Collect();
                    };
                }
                catch (Exception ex)
                {
                    displayStatus("Error in Apply applyImageTransformationClean(): " + ex.Message);
                    GC.Collect();
                };
            }

        }

Post Reply