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.
Related
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;
I have an Images folder in my visual studio project.
How can I reference the images within this folder so I can use the .exe file on other computers?
Ultimately I am trying to do the following (obviously replacing "Images/image1.jpg" with imageFile).
foreach (string imageFile in imageFolder)
{
ImageSource imageSource = new BitmapImage(new Uri("Images/image1.jpg", UriKind.Relative));
}
Using something like:
Directory.GetParent(Directory.GetCurrentDirectory()).Parent.FullName
doesn't work because the .exe could be running in any location.
If you don't need to add or remove such images during the installation of the application on the user's computer, add the images to the resources by dragging them to the Resources tab in the project properties and reference them using Properties.Resources within your code.
If you're using copying the image folder to the output of your application and taking the folder with you to the new computers you could use
var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase)
If you don't have lots of large images, why not include them as embedded resources. http://support.microsoft.com/kb/319292
Keep images (and other resources) together with exe-file (either in the same folder, which is simplest, or use directory structure).
To example:
\Bin
my.exe
my.pdb
\Help
my.html
\Resources
1.jpg
2.jpg
Then you can so something like
private static string PathRoot { get { return Path.GetDirectoryName(Path.GetDirectoryName(Application.ExecutablePath)); } }
public static string PathResources { get { return Path.Combine(PathRoot, "Resources"); } }
C# - Loading image from file resource in different assembly
I have a PNG image file which is stored in a project called SomeProject and displayed various times using XAML in that same project. In a different assembly, I now wish to access that same image. Previously I was simply specifying a relative path to the actual file which worked fine. However, when I build a release installer, the image files are packed into the SomeProject.DLL.
Is there any easy way I can access the PNG file from another assembly without simply resorting to copying the file locally to the second project? I though it might be possible using 'pack://' but I'm not having much luck.
// SomeOtherProject.SomeClass.cs ...
Image logo = new Image();
BitmapImage logoSource = new BitmapImage();
eChamSource.BeginInit();
// Following line works fine is Visual Studio, but obviously not after installation
// logoSource.UriSource = new Uri(#"..\SomeProject\Resources\Images\logo.png", UriKind.Relative);
logoSource.UriSource = new Uri("pack://application:,,,/SomeProject;component/Resources/Images/logo.png");
logoSource.EndInit();
logo.Width = 100; logo.Height = 100;
logo.Source = logoSource;
Any advice would be good.
If the images you wish to use as Content is in another assembly, you must copy them to the main projects directory.
You can use a Build event to do this:
Right click project that contains images -> Properties -> Buil Events -> edit post build to copy images to main project directory.
Then you have to use it as
pack://application:,,,/ContentFile.xaml
(Or)
If you need it in subfolder
pack://application:,,,/Subfolder/ContentFile.xaml
Have a look at this hfor more information http://msdn.microsoft.com/en-us/library/aa970069.aspx
Try to load your other assembly as followed:
Application.LoadComponent(new Uri(#"AnotherAssembly;;;component\AnotherResourceFilePath/logo.png", UriKind.Relative)));
LoadComponent function returns an object. It is up to you to cast it to the appropriate type.
I have a problem with displaying certain images in my application using C#. I am using the Image class to specify the location and the BitmapImage to specify the source. The UriSource is relative and I just specify the name. It worked for some images, but for others, the image simply does not appear. My image instance is 35x35 big and another is 100x100 big (pixels).
Anyone knows why this might be occurring and how to fix it?
Thanks.
Here's the code I used:
Image removeImage = new Image();
removeImage.HorizontalAlignment = HorizontalAlignment.Left;
removeImage.VerticalAlignment = VerticalAlignment.Top;
removeImage.Margin = new Thickness(490, 10, 0, 0);
removeImage.Width = 35;
removeImage.Height = 35;
BitmapImage source = new BitmapImage();
source.BeginInit();
source.UriSource = new Uri("delete.png", UriKind.RelativeOrAbsolute);
source.EndInit();
removeImage.Source = source;
removeImage.Stretch = Stretch.None;
removeImage.Visibility = Visibility.Visible;
removeImage.MouseDown += new MouseButtonEventHandler(removeImage_MouseDown);
Not sure about the location of image files. If images are in your current project folder then you have to set Copy To Output Directory=Copy Always property of image file from Properties Windows.
The best way that I know of to diagnose a problem like that (assuming a quick peer review of the code gets you nowhere), is to use ProcessMonitor: http://technet.microsoft.com/en-us/sysinternals/bb896645
You can use this tool to monitor all of the file activity on your machine (make sure to use the include/exclude filters to limit the noise).
It's very likely that the reason that the images are not showing up is because your application is looking for them in the wrong place (either they didn't get copied, or the relative path is off).
ProcessMonitor will log every attempt that Windows makes to access your .jpg (whether it fails or succeeds). If you search for your file name in the log, you should find it, probably along with an error message, and the full path that Windows was using to open the file.
The most common results I see are
Path that was actually being used was different from the path you needed.
The path was correct, but your files weren't there (build/copy/install problem)
The path was correct, but your web app did not have permissions to read the file.
In all those cases, ProcessMonitor will show you what happened.
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");