Problem with image path [C#, WPF] - c#

I need use images in 2 .NET assemblies. One is WPF app {myApp.exe} and second is *.dll {myDll.dll}. File are located in this file structure:
**AppFolder** consist these files and one subfolder(avatars):
-myApp.exe
-myDll.dll
-avatars {folder} consist:
-manImages.jpg
-womanImages.jpg
I try user uri in this format
new Uri(#"C:\Users\avatars\manImages.jpg", UriKind.RelativeOrAbsolute);
but this format does not work, images are empty.

I would expect
new Uri(#"avatars\manImages.jpg", UriKind.RelativeOrAbsolute);
to work?
You could also try:
new Uri(Environment.CurrentDirectory + #"\avatars\manImages.jpg", UriKind.RelativeOrAbsolute);

On the dll side you can write this:
string imgPath = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "avatars\\manImages.jpg");

Related

How to get the URI link to WAV file after compilation?

Currently experimenting with WPF here. I'm trying to use URI files to stock music in a table.
It currently works, but as expected only on my computer as it is an absolute path:
private readonly Uri[] SoundsTable = new Uri[] { new Uri(#"C:\Users\damie\Desktop\repos2\Tetrics\Tetrics\Assets\music_theme.wav"), new Uri(#"C:\Users\damie\Desktop\repos2\Tetrics\Tetrics\Assets\line_clear.wav"), };
I'm running into a problem where I can't access my music files after compiling. I can't use a relative path or determine it getting the Path.CurrentDirectory() (because my asset folder isn't generated in the compiled project).
I don't have this problem for images that can be stocked in my DLL:
`private readonly ImageSource[] tileImages = new ImageSource[] {
new BitmapImage(new Uri("Assets/TileEmpty.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TileCyan.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TileBlue.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TileOrange.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TileYellow.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TileGreen.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TilePurple.png", UriKind.Relative)),
new BitmapImage(new Uri("Assets/TileRed.png", UriKind.Relative))
};`
Does anyone have any idea of what to do here ?
I have tried to change my IDE properties for the music files, like build action and copy to output folder.
I think my answer could be here but none of what I tried worked.
Thanks a lot to anyone who responds !
If you looked inside your bin, found the compiled exe and there's no Assets folder there, then you probably haven't set the right properties on your files.
You need an Assets folder in your project.
That must have some files in it.
Their properties must be set to Build action "Content" and Copy to output directory "Copy if newer".
If you do that then you will have an assets folder with files in it within your bin after you compile.
You can then reference those files using an absolute url which would be:
Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "Assets", yourfilename)
I assume the mention of png files is just to show us something else which is working for you.
However.
There is also a pack notation in wpf which you should take a look at if you are going to reference files in xaml.
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/app-development/pack-uris-in-wpf?view=netframeworkdesktop-4.8
Relative paths are evaluated relative to the current directory. In turn, the current directory may be different depending on how exactly you launch your application. It can change during the course of an application session.
In some cases, this is provided by the logic of the application itself. For example, selecting the current folder and showing the files in it. But this is clearly not your case.
You need to get the full path to the files in the application folder (conditionally the folder with the exe file) using the relative path. The best way to do this is an explicit conversion.
Here is an example of such a transformation.
public static string RelativeToAbsoluteAppPath(string relative)
=> System.OI.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, relative);
public static string AbsoluteAppUri(string relative)
=> new Uri(RelativeToAbsoluteAppPath(string relative), UriKind.Absolute);
... = new BitmapImage(AbsoluteAppUri("Assets\music_theme.wav"));
P.S. Of course, as #Andy wrote, you must also make sure that the necessary files really exist at the specified paths.

How to create a relative path using System.Uri

I tried to create a URI like this
Uri uri = new Uri("file:///Pages/Menu/Page.xaml");
So I have a WPF project and its path is like this: C:/Programing/MyProjectName/
Now the path to my file are C:/Programing/MyProjectName/Pages/Menu/Page.xaml
as you saw above the path I give to the Uri is file:///Pages/Menu/Page.xaml when I run this I get the error can't find the part of the path C:/Pages/Menu/Page.xaml which I expect because as I said above my files path is C:/Programing/MyProjectName/Pages/Menu/Page.xaml
so my question is, is there any way to use a relative path in my Uri, I want to use a relative path because my app will not always be in the same folder.
Incase your wondering why I'm using a Uri is because I'm setting the Source property on a WPF frame and it uses Uri instead of string.
In order to load a Page, use a Resource File Pack URI:
var uri = new Uri("pack://application:,,,/Pages/Menu/Page.xaml");
Which could also be written like this:
var uri = new Uri("/Pages/Menu/Page.xaml", UriKind.Relative);

getting root of wpf app as a string

Is there another way to get the root of a wpf application as a string?
Now I'm still using
string path = AppDomain.CurrentDomain.BaseDirectory.Substring(0, (AppDomain.CurrentDomain.BaseDirectory.Length - 10));
This gives me the root as a string, but I assume this is not the right way to do it.
I also tried
string txt = System.AppDomain.CurrentDomain.BaseDirectory.ToString();
but this sends me to root/bin/debug.
I only need the root as a string
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
Another way is:
Environment.CurrentDirectory
if it was not changed.
You can find the file path of the root folder of the startup project in a WPF App like this:
string applicationDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string rootPath = Directory.GetParent(applicationDirectory).Parent.FullName;
Or to complete your example by getting the file path of the parent folder of the parent folder, you can do this:
string rootPath = Directory.GetParent(txt).Parent.FullName;
UPDATE >>>
In order to access your project Images folder, you can do this:
Path.Combine(Directory.GetParent(applicationDirectory).Parent.FullName, "Images");
You should put the images in a folder of your Visual Studio project called "Images" and set their Build Action to Resource (as shown here).
If you then get a relative image path from your DB, you would create a Pack URI and load a BitmapImage like this:
var imagePath = "Images/SomeImage.jpg"; // actually from DB
var uri = new Uri("pack://application:,,,/" + imagePath);
var bitmap = new BitmapImage(uri);

WPF load image from folder

I have images that is not located in resources but on the disk. The folder is relative to application. I used:
Overview_Picture.Source = new BitmapImage(new Uri(String.Format("file:///{0}/../MyImages /myim.jpg", Directory.GetCurrentDirectory())));
Overview_Picture.Source = new BitmapImage(uriSource);
But those type of code created many problems and messed up GetCurrentDirectory returns that sometime ok and some times not.
So, MyImages folder is located next to Debug folder, how can I use them images there and not as I done, In some other more right way?
As mentioned oftentimes here on SO, the GetCurrentDirectory method does by definition not always return the directory your assembly resides in, but the current working directory. There is a big difference between the two.
What you need is the current assembly folder (and the parent of that). Also, I'm not sure whether it is wanted that the pictures are one folder above the installation folder (which is basically what you're saying when you say they are one level above the Debug folder - in real life that would be one folder above the folder the application is installed to).
Use the following:
string currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string currentAssemblyParentPath = Path.GetDirectoryName(currentAssemblyPath);
Overview_Picture.Source = new BitmapImage(new Uri(String.Format("file:///{0}/MyImages/myim.jpg", currentAssemblyParentPath)));
Also, there's a stray space after MyImages, which I removed.
An alternative to constructing an absolute Uri from a relative file path would be to just open a FileStream from the relative path, and assign that to the BitmapImage's StreamSource property. Note however that you also have to set BitmapCacheOption.OnLoad when you want to close the stream right after initializing the BitmapImage.
var bitmap = new BitmapImage();
using (var stream = new FileStream("../MyImages/myim.jpg", FileMode.Open))
{
bitmap.BeginInit();
bitmap.CacheOption = BitmapCacheOption.OnLoad;
bitmap.StreamSource = stream;
bitmap.EndInit();
bitmap.Freeze(); // optional
}
Overview_Picture.Source = bitmap;

Can't find path to Image in pictureBox,Image = new Bitmap(path)

I need to load a picture to a pictureBox in a WindowsCE 6.0 . When I run the program in the mobile it tells me that it can't find the path.
This is my code:
this.pictureBox1.Image = new Bitmap(#" Data Source = \Program Files\Data\Image20120523_1.jpeg ");
I already tried with this paths to but it doesn't work:
path1: #"\Program Files\Data\Image20120523_1.jpeg"
path2: "\Program Files\Data\Image20120523_1.jpeg"
I have a database located in the same path and when I use it to make the connection it works ok, why it isn't working to load the image?
SOLUTION
This path works ok:
this.pictureBox1.Image = new Bitmap(#"\Program Files\Data\Image20120523_1.jpeg");
thanks for your help!
You need to use simple path to the image file here. Like this:
this.pictureBox1.Image = new Bitmap(#"E:\temp\photo\IMG_1461.JPG");

Categories

Resources