Search code examples
c#filegdi+openfiledialogimaging

Cannot save image in a folder that I created


I'm currently creating an image resizing program with C# Windows Forms. So, I make it overwrite existing images with resized images. I also made a function that makes Originals folder and save originals images in it, in order that when I need original images I can use images in the folder. Below is th

for (int k = 0; k < openFileDialog.FileNames.Length; k++)
{
   fileNames.Add(openFileDialog.FileNames[k]);

   using (Stream stream = File.OpenRead(fileNames[k]))
   {
       //System.Collections.Generic.List<System.Drawing.Image>
       selectedImages.Add(Image.FromStream(stream));
       resizedImages.Add(Image.FromStream(stream));                                                 
   }
   filesCount++;
}

for (int k = 0; k < filesCount; k++)
{
    string filePath = Path.GetDirectoryName(fileNames[k]);
    Directory.CreateDirectory(filePath + "\\Originals");

    string selectedFileName = filePath + "\\Originals\\" + Path.GetFileName(fileNames[k]);
    string resizedFileName = filePath + "\\" + Path.GetFileNameWithoutExtension(fileNames[k]) + ".jpg";

    //GetImageFormat is my function that return ImageFormat. It has no problem.
    selectedImages[k].Save(selectedFileName, GetImageFormat(Path.GetExtension(fileNames[k])));
    resizedImages[k].Save(resizedFileName, ImageFormat.Jpeg);
}

The problem here is that selectedImages[k].Save emit GDI+ generic error although resizedImages[k].Save works completely fine. I think it's because of the folder that I created but I can't find a solution.


Solution

  • I think it's because of the folder that I created but I can't find a solution.

    Wrong Directory.CreateDirectory will throw an exception if it cant create it when it does not already exist.


    So lets address the problems you have

    • \\Originals\\ don't do this, if you need a back slash use @\Originals\
    • If you are going to combine a path, use Path.Combine
    • Don't use for when you can use a foreach
    • there was no need to make so many lists and loops
    • if you create an image you need to dispose it
    • And the biggest one is, do not try to save a file over a file with an open file handle.

    At times like this, you need to step back from your code and remove all the redundancy. Most of your code was absolutely not needed, and it makes your life harder to debug

    foreach (var file in openFileDialog.FileNames)
    {
       var name = Path.GetFileName(file);
       var path = Path.GetDirectoryName(file);
       var newPath = Path.Combine(path, "Originals");
       var newName = $"{Path.GetFileNameWithoutExtension(name)}.jpg";
    
       Directory.CreateDirectory(newPath);
    
       var newFullPath = Path.Combine(newPath, name);
       // why do anything fancy when you just want to move it
       File.Move(file, newFullPath);
    
       // lets open that file from there, so we don't accidentally cause the same 
       // problem again, then save it
       using (var image = Image.FromFile(newFullPath))
          image.Save(Path.Combine(path, newName), ImageFormat.Jpeg);  
    }
    

    Although i am not sure what your actual problem was, i am assuming it was the GetImageFormat method, or you were trying to overwrite a file with an open handle. However, in the spirit of what i think you are trying to achieve, this will probably just work