Setting WPF image source in code

591,762

Solution 1

After having the same problem as you and doing some reading, I discovered the solution - Pack URIs.

I did the following in code:

Image finalImage = new Image();
finalImage.Width = 80;
...
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png");
logo.EndInit();
...
finalImage.Source = logo;

Or shorter, by using another BitmapImage constructor:

finalImage.Source = new BitmapImage(
    new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));

The URI is broken out into parts:

  • Authority: application:///
  • Path: The name of a resource file that is compiled into a referenced assembly. The path must conform to the following format: AssemblyShortName[;Version][;PublicKey];component/Path

    • AssemblyShortName: the short name for the referenced assembly.
    • ;Version [optional]: the version of the referenced assembly that contains the resource file. This is used when two or more referenced assemblies with the same short name are loaded.
    • ;PublicKey [optional]: the public key that was used to sign the referenced assembly. This is used when two or more referenced assemblies with the same short name are loaded.
    • ;component: specifies that the assembly being referred to is referenced from the local assembly.
    • /Path: the name of the resource file, including its path, relative to the root of the referenced assembly's project folder.

The three slashes after application: have to be replaced with commas:

Note: The authority component of a pack URI is an embedded URI that points to a package and must conform to RFC 2396. Additionally, the "/" character must be replaced with the "," character, and reserved characters such as "%" and "?" must be escaped. See the OPC for details.

And of course, make sure you set the build action on your image to Resource.

Solution 2

var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);

This will load a image called "Untitled.png" in a folder called "Images" with its "Build Action" set to "Resource" in an assembly called "WpfApplication1".

Solution 3

This is a bit less code and can be done in a single line.

string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;

Solution 4

Very easy:

To set a menu item's image dynamically, only do the following:

MyMenuItem.ImageSource = 
    new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));

...whereas "icon.ico" can be located everywhere (currently it's located in the 'Resources' directory) and must be linked as Resource...

Solution 5

Simplest way:

var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
Share:
591,762
Torbjørn
Author by

Torbjørn

I'm a developer and technical manager working for LINK Mobility, Norway. Passionate about most languages, but .NET dev by day. More about me at http://www.kjempekjekt.com/cv

Updated on July 08, 2022

Comments

  • Torbjørn
    Torbjørn almost 2 years

    I'm trying to set a WPF image's source in code. The image is embedded as a resource in the project. By looking at examples I've come up with the below code. For some reason it doesn't work - the image does not show up.

    By debugging I can see that the stream contains the image data. So what's wrong?

    Assembly asm = Assembly.GetExecutingAssembly();
    Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
    PngBitmapDecoder iconDecoder = new PngBitmapDecoder(iconStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    ImageSource iconSource = iconDecoder.Frames[0];
    _icon.Source = iconSource;
    

    The icon is defined something like this: <Image x:Name="_icon" Width="16" Height="16" />

  • Torbjørn
    Torbjørn over 15 years
    LOL! Why make it easy when you first can make it difficult :) I'll try your simple solution before I accept though...
  • Torbjørn
    Torbjørn over 15 years
    Actually this didn't help me at all. Maybe I'm stupid :( Don't have time to look more closely right now (pet project). Would like more answers for when I get back to it :)
  • si618
    si618 over 14 years
    Thanks for that. One issue that tripped me up as a noob to wpf, image must be marked as resource for this to work.
  • Torbjørn
    Torbjørn over 14 years
    Yes, this was the solution I found myself after some trial and error. Thanks for the thorough explanation. Answer accepted!
  • Torbjørn
    Torbjørn over 14 years
    I don't know why this was needed though, and why the other answers didn't work for me...
  • Thomas Stock
    Thomas Stock about 14 years
    the other answers in this and other questions didn't work for me either. This one works perfectly. Thanks.
  • gjvdkamp
    gjvdkamp over 13 years
    Shorter = better. I had to set it as @"/folder/image.png" though but then it worked fine. Thanks!
  • Sangram Nandkhile
    Sangram Nandkhile about 13 years
    This solution Gave me an exception so i tried Jared Harley's solution and it worked...
  • Qwertie
    Qwertie about 13 years
    Okay, but isn't there some method or class that the XAML parser uses to convert the simple path string to an ImageSource? Couldn't we just use that?
  • Qwertie
    Qwertie about 13 years
    I think the problem is that WPF doesn't "like" the traditional approach of putting resources in resx files. Instead you are supposed to add the image directly to your project and set its Build Action property to Resource. I'm don't know what the difference is (in term physical file format) between the two approaches.
  • Jerry Nixon
    Jerry Nixon over 12 years
    Ensure the Build Action is Content
  • Sven
    Sven about 12 years
    the most important thing is "UriKind.RelativeOrAbsolute" - other examples always threw exceptions
  • Hamzeh Soboh
    Hamzeh Soboh almost 11 years
    var uriSource = new Uri("Images/Untitled.png", UriKind.Relative); would be sufficient
  • joshcomley
    joshcomley about 10 years
    This is definitely the best answer, utilising .NETs own implementation
  • Scott Solmer
    Scott Solmer almost 10 years
    This solution doesn't work for me. I get a compile error: Cannot implicitly convert type System.Windows.Media.Imaging.BitmapImage to System.Windows.Controls.Image...
  • hkarask
    hkarask over 9 years
    Add the image to the grid from toolbox, add a name to it (e.g. TestImage) and set the image path from properties menu. Then write var testImage = TestImage to startup code, add a breakpoint, debug and copy the source value.
  • pStan
    pStan over 9 years
    ... and much easier. Thanks Hamzeh
  • secretgenes
    secretgenes over 8 years
    what if we need to set the height and width of image i.e icon.png? Because by using _image.height and _image.width it sets the image window not the actual image i.e icon.png.
  • HaloMediaz
    HaloMediaz over 8 years
    When I assign the imagesource, it's just showing up blank :(
  • Myosotis
    Myosotis over 7 years
    BeginInit() doesn't seem to exist in WPF.
  • maulik kansara
    maulik kansara over 7 years
    It is available check below link msdn.microsoft.com/en-us/library/…
  • Clemens
    Clemens over 6 years
    I often see this snippet copied into other posts, where people usually ignore the existence of the BitmapImage(Uri) constructor, which helps to avoid the need for calling BeginInit and EndInit. I've added it here.
  • Rouzbeh Zarandi
    Rouzbeh Zarandi over 5 years
    @HaloMediaz path may be wrong ....eg you have Resources but you you may write it Resource
  • Psiloc
    Psiloc over 5 years
    This worked for me, and far more straightforward than the absolute URIs in the other answers.
  • Slate
    Slate over 5 years
    This solution didn't work for me, however appending pack://application:,,, to the Uri does.
  • mins
    mins over 4 years
    Question: "The image is embedded as a resource in the project", answer: "Here is an example [for an image] located somewhere on disc rather than build as resource".
  • Yessir
    Yessir over 3 years
    Where do i get the assembly name from?
  • Daniel Möller
    Daniel Möller over 2 years
    Great solution. Can easily return a string and use Binding without caring about the assembly name.