Search code examples
c#system.drawing

Getting exception when trying to save an image that was edited locally


I'm trying to edit an image by including a water mark on it. I make my changes using Graphics and when I try to save the file it throws me an exception Message:"A generic error occurred in GDI+."

Below is my code:

    public static void Test()
    {
        try
        {
            Bitmap bmpPic = new Bitmap(Image.FromFile("Desktop/cropped/cropped/croppedsent1386.jpeg"));

            using (Graphics g = Graphics.FromImage(bmpPic))
            {
                Brush brush = new SolidBrush(Color.FromArgb(80, 255, 255, 255));
                Point postionWaterMark = new Point((bmpPic.Width / 6), (bmpPic.Height / 2));
                g.DrawString("Identifid", new System.Drawing.Font("Arial", 30, FontStyle.Bold, GraphicsUnit.Pixel), brush, postionWaterMark);

            }

            string filepath = "Desktop/cropped/cropped/croppedsent1386.jpeg";

            bmpPic.Save(filepath, ImageFormat.Jpeg);
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex);
        }

        Console.WriteLine("End of test ");
    }

-Stack Trace-

        StackTrace  "   at System.Drawing.SafeNativeMethods.Gdip.CheckStatus(Int32 status)\r\n   at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)\r\n   at System.Drawing.Image.Save(String filename, ImageFormat format)\r\n   at ConsoleWatermark.Program.Test() in C:\\Users\\xavie\\source\\repos\\Samples\\ConsoleWatermark\\Program.cs:line 49" 

I'm stumped as to why this is failing as I have permissions to edit files .


Solution

  • Error appears because you trying to overwrite (when bmpPic.Save()) same image file, which you already loaded as Bitmap. Until Bitmap wouldn't be disposed - file would be locked by it. To solve, you should save new watermarked image to an other new file:

    string filepath = ".../croppedsent1386_WATERMARKED.jpeg"; // <--- New file
    bmpPic.Save(filepath, ImageFormat.Jpeg);
    

    Complete version (with few notations):

    static void Main(string[] args)
    {
        try
        {
            // Source image file
            string imageFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "myImage.png");
    
            // Add "using" to bitmap too for proper disposage and to release file after completion
            using (Bitmap bitmap = new Bitmap(Image.FromFile(imageFile)))
            {
                using (Graphics g = Graphics.FromImage(bitmap))
                {
                    Brush brush = new SolidBrush(Color.FromArgb(80, 255, 255, 255));
                    Point watermarkPosition = new Point(bitmap.Width / 6, bitmap.Height / 2);
    
                    g.DrawString("IDENTIFID", new Font("Arial", 30, FontStyle.Bold, GraphicsUnit.Pixel), brush, watermarkPosition);
    
                    // Save to a new file
                    string newImageFile = imageFile.Replace("myImage.png", "myImage_WATERMARKED.png");
                    bitmap.Save(newImageFile, ImageFormat.Png);
                }
            }
    
            Console.WriteLine("Image saved!");
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message + "\n\nStack trace:\n" + ex.StackTrace);
        }
    
        Console.ReadKey();
    }