How does WPF reference images added as an image resource? - c#

I have a WPF application where I added the images as resources to the project (not from project settings, like how the 2nd answer does it here), so they are under a folder. I use them like this in xaml:
<Image Width="32" Height="32" Source="/Images/Effect.png" />
When I build this app, only the dependent dlls and the app itself is put into the Debug/Release folder. The Icons that reside inside the project and the actual folders and files are inside the project's folder. Those aren't copied into Debug/Release.
I am able to run this application from anywhere, and the images work, so it must be turning the relative paths to hard coded paths?
If that's the case, how am I gonna be able to distribute those Image files to other machines?
I want to be able to always have the Images relative to the app, both in reference and on disk.
Is this the best way or is there a better way? In the end, I want to easily distribute these images and the app to other machines.

The images are getting compiled into the assemblies as resources. They are not referenced from their original location on your disk.
When you specify your Image.Source like that, WPF looks for the appropriate image in the current assembly. You can also reference images (as well as other resources) that reside in referenced assemblies. Here is some detailed explanation about the resource URI format in WPF (called "Pack URI").

Related

Not able to reference Image source with relative path in xaml

I have created a ClassLibrary project, and added a xaml of Window type.
I wrote a console application and showing this wpf window.
The problem is I have to show an Icon in this window.
If I am using following code it is not working
<Image Source="../Images/Folder-icon.png"></Image>
When I give some hard coded path like
<Image Source="E:\MyApp\Images\Folder-icon.png"></Image>
it works.
Why I have to give an hard coded path value? Is there any solution?
Hope I gave enough information. Please help I am struggling with this problem for more that 2 hours.
If Images folder is added in same project of its usage, this should work for you:
<Image Source="/Images/Folder-icon.png"/>
Or use Pack Uri specifically:
<Image Source="pack://application:,,,/Images/Folder-icon.png"/>
In case image resides in different project than current project where your XAML resides, you have to use more verbose definition of Pack URI where you have to specify the assembly name where image is added.
<Image Source="pack://application:,,,/Assembly;component/Images/Folder-icon.png"/>
Replace Assembly with actual assembly name where image is added into.
Also make sure Build Action is set to Resource for file Folder-icon.png.
UPDATE:
More verbose definition of Pack URI works in sample as well. Try this out:
<Image Source="pack://application:,,,/ClassLibrary1;component/Folder-icon.png"/>
Answers to such questions are often confusing because the principles/prerequisites for the solution to work are not explained correctly. This is the case with the currently selected answer too. So it's a good thing to be aware of:
The different ways to manage and reference a file/resource added to the project.
How to specify in the markup the URL for a file managed as Content.
The non-required use of the pack URI instead of the simple URL
Things to consider:
1. How to declare the type of file/resource you are adding to your project.
This is done by adding appropriate folder and files to the project using the Solution Explorer in VS, e.g. in a subfolder Images:
and specifying properties for each added file (on the right side below):
The Build Action is set to Content and the Copy To Output Directory is set to Copy if newer. This is how files should be added when you don't want them to be embedded into the assembly.
For reference, the Content option is one of the possible options to access a file in WPF. Other options include Resource (either embedded in the current assembly, or in another assembly of the same application) and Site of Origin to access a file which has no relationship with the current application:
Source
Content type files are linked to the executable (assembly) only by the relative path they are stored. The relative URL is stored in assembly metadata. These files are expected to be found at execution time, but they can be changed/updated without recompiling the assembly.
The Copy if Newer value means the compiler will take care of copying the original file to the right place during the assembly building process, so that the relative path is preserved, e.g. if a file is located in the subfolder Images of the project, e.g. MyProject/Images then a copy will be created in MyProject/bin/Debug/Images when the application is compiled in debug mode. The assembly being built in MyProject/bin/Debug, the relative path is the same.
2. How to specify a Content file URL in the markup.
This is the easy part, and usually the only one explained. But it works only if the previous step has been done correctly.
To use a content file, just use the markup shortcut of the relative path (relative to the assembly): <Image Source="Images/Lighthouse.jpg"/> (there is no leading /).
Other cases, where the file is not declared as Content type (e.g. an image which must be embedded into the assembly as a Resource, or a file which must be loaded from the network) involve syntax variations with the simple URL replaced by a pack URI.
3. Non-required / excessive use of the pack URI.
As the URI scheme can be used to reference anything, the pack URI solution is often proposed to also reference files declared as Content. For our example, the equivalent pack URI would be: pack://application:,,,/Images/Lighthouse.jpg (note the leading /).
However the URL shortcut is more appropriate, and less error-prone for a standalone file which location relative to the assembly is known at design time.
For a more detailed view see:
WPF Application Resource, Content, and Data Files
I got this working by:
Name of my WPF User Control project: WpfControls
Name of the folder containing the image: Images
Name of the imgae file: Asdf.png
Include the folder and image file into the WpfControls project
The image file's Build Action set to Resource
The Source property in the Image tag set to:
<Image Source=/WpfControls;Component/Images/Asdf.png" />

Best way to share assets like images between projects

I'd like to share some assets like icons between multiple WinRT projects.
With WPF this was a no-brainer (well almost):
create a library project for the assets
mark the assets as resources to embed them into the generated assembly
reference the assets project from the other projects
reference the icons from the XAML code using the somewhat strange "pack" URI format.
What's the best way of sharing them with Windows Runtime?
Is there such a resource embedding and sharing capability, or any other solution?
If no I guess I could add them to every project with "Copy as link" but I hope there is a clean way.
EDIT: I've started to do it naively like I would in a WPF project:
I've created a new library project "Assets" and added the image inside as "Content"
I've referenced this project from my main project
But I can't reference the image with the new URI format:
<Image Source="ms-resource://Assets/Files/Mushroom.png"></Image>
So finally I got the correct result.
Here is the full process:
create your library project, add your image and set its build action as "Content"
reference the library from your main project
To reference the image itself you must:
use the "ms-appx" schema, not "ms-resource" as you might find on Google
specify an absolute path with /// not //
<Image Source="ms-appx:///Assets/Mushroom.png">
And above all don't trust the Visual Studio designer:
when you get it right it may not display the image
when you get it wrong it may display it (from a previous success) but at runtime you'll get nothing!
Hope this helps...
It is very simple. Right click on the folder where you want the images (e.g., an Assets folder in the new Project) and the select "Add/Existing Item". Then select the images that you need and be sure to change the "Add" button, to "Add as Link". Done.

what will happen to images in the Resources directory once the app is packed and how safe are those images for the app?

the Resources folder typically contains all the app images (those 16 X16) that we use to look our apps good. I haven't dealt with installation and resources folder before therefore :
When application needs to be deployed, what would happen to those images in that Resource folder?
I haven't tried this before so when I install the application where would that resource folder be saved?
If the installation creates another resource folder to keep those images, then what if a user manually deletes that folder? App would crash? what is the solution to overcome this?
I've heard some place the images in a .dll file, is this a common practice?
thanks
When you build your application, Visual Studio invokes the resgen.exe tool to convert your application resources into an internal class called Resources. This class is contained in the Resources.Designer.cs file which is nested under the Resources.resx file in Solution Explorer. The Resources class encapsulates all your project resources into static readonly get properties as a way of providing strongly-typed resources at run-time. When you build through the Visual C# IDE, all the encapsulated resource data, including both the resources that were embedded into the .resx file and the linked files, is compiled directly into the application assembly (the .exe or .dll file). In other words, the Visual C# IDE always uses the /resource compiler option. If you build from the command line, you can specify the /linkresource compiler option that will enable you to deploy resources in a separate file from the main application assembly. This is an advanced scenario and is only necessary in certain rare situations. A more common scenario for deploying resources separately from the main application assembly is to use satellite assemblies as discussed below.
All your queries is answered above
i.e.
When application needs to be deployed, what would happen to those images in that Resource folder?
I haven't tried this before so when I install the application where would that resource folder be saved?
If the installation creates another resource folder to keep those images, then what if a user manually deletes that folder? App would crash? what is the solution to overcome this?
I've heard some place the images in a .dll file, is this a common practice?
For More information
http://msdn.microsoft.com/en-us/library/7k989cfy(v=vs.80).aspx

C# problem with Packing the supporting files with EXE, while publishing the project

I am using visual studio 2005, (.net version is 2.0+) to create a windows application. The functionality of the project is matching with the ideal design, there is just one problem in publishing the project.
I use MouseHover method to change the picture(image) used in intention to make attractive UI, when I hover the mouse pointer over the picture .. some other pic is loaded in-place of it .. and in mouseleave method the same picture is retained back.
Now the problem is while debugging this functionality works properly,
But when published, and used, the window won't load the image (as the installed folder doesn't contain these images) .. How to bind the supporting files like images, text files and any other files like xml with EXE??
I mean is there any ideal way to publish the project??
In your project, ensure that the images are set to Copy Always or Copy if Newer on the Copy To Output Folder property (F4).
That should ensure that when doing an XCopy deploy the images will be in the right folder (you will proabably need to change the logic for finding the image paths, so the application finds them in the right directory).
If you are using deployment project that will generate .MSI for your application, just right click on the project, click add files and then pick the images from your project directory.
Those files will be (by default) be deployed into the application target directory, and your end-user app will be able to access it.
You can package them as Embedded Resources.
To embed them, make sure that when the resources are selected in the Solution Explorer that the 'Build Action' in the Properties window is set to 'Embedded Resource'.
Here is an example with sample project on how to embed images : How to use embedded resources in .Net

Include and Reference Resource File from C# class

I have an image that is used in some PDF files that my C# application generates. I know how to reference the image file when it is located in my workspace, but when I compile the program, I don't see the image anywhere in the compiled directory.
Can someone tell me what happened to that file, or do I have to manually package the file along with my program when I send the program to the users? I added the image to the workspace by drag-drop to the resource directory of one of my namespaces.
Check the file's properties in Visual Studio. Have you set the CopyToOutputDirectory property to something besides Do not copy?
Hmm... I'm not sure about the whole drag-drop business, but if it's all working the resource will have been embedded into your assembly.
I suggest you have a look with Reflector - you can see the resources embedded within assemblies using that.
Have a look at the build properties for the item in Solution Explorer - in particular, if the build action is Embedded Resource then it will indeed be built into the assembly.

Categories

Resources