0

I am attempting to copy a selected image to a folder and then want to display it with an Image object. The copying works fine, but when I want to display it it seems like the program cannot find it. Displaying the image only works if I manually use "add existing Item". Is there a way to add it automatically?

Here is my code:

string name = "image1";

OpenFileDialog dialog = new OpenFileDialog();

Nullable<bool> dialogOK = dialog.ShowDialog();

if(dialogOK == true)
{
     File.Copy(dialog.FileName, @"..\..\Images\" + name + ".png", true);


     image.Source = new BitmapImage(new Uri(@"Images\" + name + ".png", UriKind.Relative));
}

("image" is defined in xaml)

codewise
  • 626
  • 8
  • 23

1 Answers1

1

It seems safer to use an absolute path for loading the BitmapImage:

var dialog = new OpenFileDialog();

if (dialog.ShowDialog() == true)
{
    var targetFile = @"..\..\Images\" + name + ".png";
    var currentDir = Environment.CurrentDirectory;
    var targetPath = Path.Combine(currentDir, targetFile);
    var targetDir = Path.GetDirectoryName(targetPath);

    Directory.CreateDirectory(targetDir);

    File.Copy(dialog.FileName, targetPath, true);

    image.Source = new BitmapImage(new Uri(targetPath));
}

In order to release the file directly after loading the BitmapImage, load it from a FileStream:

BitmapImage bitmap = new BitmapImage();

using (var stream = File.OpenRead(targetPath))
{
    bitmap.BeginInit();
    bitmap.CacheOption = BitmapCacheOption.OnLoad;
    bitmap.StreamSource = stream;
    bitmap.EndInit();
}

image.Source = bitmap;
Clemens
  • 123,504
  • 12
  • 155
  • 268
  • Thanks for your help! I already tried a similar thing (giving the absolute path @"C:\Users\..."). The Problem with that is when i want to delete the Image with `File.Delete(@"C:\Users\...")` i get an error because the path is currently used by the picture. Even if i set ´image.Source = null` the garbagecollector won´t delete it. But when i use a relative path this error doesn´t appear but i ran into the issue i described above. So is there a way to do it with a relative path? @Clemens – mountygaming Apr 16 '20 at 13:37
  • A relative path won't help. See the edited answer, or here: https://stackoverflow.com/a/13265190/1136211 – Clemens Apr 16 '20 at 13:39
  • Thank you so much. That was the missing piece! Just out of curiosity what is this line for? `Directory.CreateDirectory(targetDir);` – mountygaming Apr 16 '20 at 15:24
  • It creates all subdirectories of the target path, just in case they do not already exist. So it's not strictly necessary. – Clemens Apr 16 '20 at 15:49
  • Thanks again Clemens! – mountygaming Apr 16 '20 at 16:37
  • This may possibly hit permission issues, especially if it is in program files folders. You could also create and use a my documents sub folder for storing temporary or program used files. – Slipoch Apr 28 '20 at 00:02