i have a small app in C# winform. It work great but i don't understand how to change the image of a picture box in code :
i have this directory for my image :
myProjectDirectory/bin/Pics/myImage.jpg
and this code give me an FileNotFoundException :
this.imgInvader.Image = Image.FromFile("../Pics/invader2.jpg");
i don't understand because i see on stackoverflow that FromFile method begin at bin/Release. So a ../Pics/myImage.jpg should work no ?
Thx
Use the relative path of the image.
this.imgInvader.Image = Image.FromFile(#"bin\Pics\invader2.jpg");
Here give the path from the location where your code behind file is located. Suppose if your file is in root directory and if your images are in bin/Pics/ folder then the above code works. It automatically gets the path related to the location the program is running from.
Trying to reference image files that are outside the executable output directory is incredibly fragile. There are lots of ways it can go wrong (unfortunately, there's not enough context in your question for anyone to know exactly which of these ways is your specific problem).
If you must use files on disk to store your image resources, then they should be copied into the build output directory (i.e. "Release") and referenced there. Add the file to your Visual Studio project, select it, and in the properties window, set the "Build Action" value to "Content". If the file is in a folder under the project, then it will also be copied to a folder of the same name in the output directory.
If you do use files on disk, the other thing to make sure you do is find the executable's directory (e.g. via Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)) and then combine that with your expected relative path (e.g. just the file name, or the file name under whatever folder/subdirectory you gave it in the project, if you did) using the Path.Combine() method, and then using that absolute file name as the source. Otherwise, your code can be confused by changes in the current directory made elsewhere in your program (basically, don't ever rely on the current directory…global state like that is too easy to get mixed up, once you get into the habit of using it).
For example:
string exeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string imageFileName = Path.Combine(exeDirectory, "invader2.jpg");
Now, all that said, IMHO it is probably a better idea to add your images as resources in the executable itself, and then reference them from the Properties.Resources class. Then the images are always with the executable, because they are in the same file. The code is a lot easier too, because you're just referencing properties in the Resources class that return the actual Image objects you need.
As the previous comment stated, using resources outside of your exe is not advised however you can still do this by using the Path.GetDirectoryName Method.
I am left to question why your resources are based outside of your exe, why not embed it into your resources located in properties > resources.resx and simply call it with imgInvader.Image = Properties.Resources.FileNamehere; it is a lot safer than trusting the external environment.
Related
I have a series of files in my program, which take user input and store them as a KeyValuePair some of them have names, most of them just have a numeric ID associated with them. This information needs to remain persistent across the application starting and stopping. I've tried several approaches but I can't get any of them to work quite right.
My approach was to simply have a Content folder, full of .json files I knew I could expect. When the program first launched, it reads the file using the Newtonsoft JSON Deserializer, and loads it into the appropriate place in memory as a List<KeyValuePair<int,string>. That all works fine, but getting the path to the File has proven exceedingly difficult.
I started with literals, but then realized I need to be able to have the program in any directory. So then I tried finding the absolute path of the file, given its relative name to the project. Still doesn't work because debugging and publish directories, as well as copy on compile stuff. As a minor issue, I also am annoyed that I still needed to use a string literal here.
SO, I resolved to make it a .resx file. This immediately failed, because you can't edit a .resx at runtime. So, referenced the external .json file from the .resx. The process of getting the URI or Path from the .resx proved excruciating if not impossible. I first tried
Assembly.GetExecutingAssembly().GetManifestResourceStream("MyJsonFile.Json") which I hoped would work but didn't.
So I had it print out String.Join(Assembly.GetExecutingAssembly().GetManifestResourceNames()) all I got out from the console wasMyNamespace.Properties.Resources.resources` and no indication of how to further extricate the location of any particular resource.
I even tried Assembly.GetExecutingAssembly().Location and couldn't do anything useful form there because it referred to my exe in the debug folder.
My last hope was an embeded content file, but I can't save those during the run time either. I can refer to the properly with URIs instead of literal strings, but I can't save them mid runtime, like I would need to in order to save on edit, or to even save from memory on close.
If anyone can give me clear information on how to extricate the URI or Path of a file in my solution without using literals, I would greatly appreciate it. Because I am getting nowhere with research I've done and the tools I have.
If you put it in your bin/debug folder, you do not need the path. You just need the names of the files.
Otherwise put the path in the .config file and then read it from there like this:
<appSettings>
<add key="Path" value="PathToFiles"/>
</appSettings>
Then get the setting like this:
using System.Configuration;
string path = ConfigurationManager.AppSettings["Path"];
Make sure to import
I am loading an image in my program with this code:
Image img = new Bitmap(#"C:\Users\******\Desktop\*****\bin\Debug\image.png");
I would like to keep the location static so I don't have to manually edit the path when I run the program on a different PC.
I am experimenting with the apps.config file as I have heard this is where my solution will lie.
Any help with this would be appreciated!
Why not use Environment.SpecialFolder?
This isn't static, obviously, but you wouldn't have to edit anything. You would really only have to create the folders on the desktop if they don't already exist.
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Or use System.Environment.CurrentDirectory since it looks like that's where you're putting it anyway...
Image img = new Bitmap(Environment.CurrentDirectory + #"\image.png");
A better solution would be to embed it in a resx file as part of your assembly. That way you wouldn't have to worry about the file being located any differently.
The static property
AppDomain.CurrentDomain.BaseDirectory
points to the path from where the application was started, even if the current directory points somewhere else. You can use this to locate files that are in the same directory as the executable. However, for small images (i.e. GUI components), embedding them as resources is the way to go.
When I run SomePicturebox.Load("Foo.bmp") and there is a Foo.bmp in the application's startup folder, it will load this image. However I have a case where the image is not loaded (when the application is started by an installer, namely).
Now I am wondering: Is there a default path that is searched by the framework when the path is not fully qualified? How can I show this path at runtime (to reveal why the image is not loaded in some cases)?
I tried looking at the Picturebox.ImageLocation property but this said just "Foo.bmp" without a path.
This is related to WinForms, .NET Framework 4.
Answers in both C# and VB.NET are very welcome.
In VB.NET
Dim directory as String = My.Application.Info.DirectoryPath
In C#
string directory = AppDomain.CurrentDomain.BaseDirectory;
I tested and AlexC was correct and I have updated this answer.
The best way to get the current value for the path is with System.IO.Directory.GetCurrentDirectory().
Rather than dealing with this ambiguity, though, it is better to make sure you fully qualify the path. To get paths on a system that can change, you should use the System.Environment.GetFolderPath call. For example, if you want the user's documents folder:
var path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
If you happen to be using an open file dialog the following is another call I often find helpful:
var fullPath = System.IO.Path.GetFullPath(selectedFile);
There are quite a few other routines in the System.IO.Path namespace that can help you with making sure that your file and path names are always fully qualified. Hope these help!
Note - My answer is in C#
INTRO:
Good day dear coders! I took a look around and wasn't quite able to find answer to my simple question, tho some questions do answer my question, however they seem to be advanced for me to fathom so I'm printing here my simple situation.
QUESTION:
I want to change BackgroundImage or Image of PictureBox and thats how I am doing this:
PictureBox.Image = new Bitmap(#"C:\Users\Ailayna\documents\visual studio 2012\Projects\FormCritterTalking\FormCritterTalking\Character Pictures\CharacterNormal.png");
This picture located in one of my project folders and some how writing whole path to the picture makes no logical sense to me, since I have included all needed pictures to the project, in specific project's folder and I wonder is there a more efficient way of changing picture rather than specifying the whole path of where picture is located?
Is there a way to directly access my folder where my project pictures located using code, like for example: PictureBox.Image = FolderName.PictureName;
I would like to know how are you guys doing this in more efficient and neat way? And another thing is, do I always have to say "new Bitmap"? Can it be something else?
Is there a way to directly access my folder where my project pictures
located using code, like for example: PictureBox.Image =
FolderName.PictureName;
Yes, there is. It's called resources.
In your project select properties then chose resources. Add image.
Access it:
yourProjectName.Properties.Resources.imageName
However I'd recommend to use streams to access images. This is the right way, especially in case of bitmaps. Do not forget to dispose it afterwards. See my answer here how to do this.
I am not aware of any PictureBox control in WPF but if you are looking for the same in WPF You can do it like this in XAML:
<Image Source="/MyProject.UI.Common;component/Images/Cut.png"/>
Here your Image is located inside "Images" folder.
Disclaimer: Since you're loading a picture directly off the hard drive (and I'm assuming it's working) I'm guessing we're talking about a WinForms project.
There are a number of options you can choose from.
The simplest of which is probably getting the current application assembly folder and using that:
How do I get the path of the assembly the code is in?
var dir = AppDomain.CurrentDomain.BaseDirectory;
The images should be copied along with the executable. Then you can either use the code above to get the current directory OR you can try and rely on a relative path (from where the executable is located to the images).
Another option is to add the pictures as resources - these will be part of your application, but the procedure of reading them is a bit more complex.
I need to get the temp file to see what happened because the actual file is never output. However, I can't seem to find where the temp file is created.
I need to find this out without writing code or building the application because there are too many dependencies scattered all over the place. I would not be able to deploy a debug version.
That method returns the path of a temporary file. The path will tell you where its pointing.
For example:
Console.WriteLine(Path.GetTempFileName());
produces:
C:\Users\will\AppData\Local\Temp\tmp9BD5.tmp
for me on this machine, because the TEMP environment variable is pointing to C:\Users\will\AppData\Local\Temp\
But the whole point of a method like GetTempFileName is that you shouldn't have to care where the file ends up. On the off-chance that you do, you can always get there at command prompts or file-open dialogs by using %TEMP%