本文翻译自:Setting WPF image source in code
I'm trying to set a WPF image's source in code. 我正在尝试在代码中设置WPF图像的源代码。 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" />
图标的定义如下: <Image x:Name="_icon" Width="16" Height="16" />
#1楼
参考:https://stackoom.com/question/1T3b/在代码中设置WPF图像源
#2楼
Here is an example that sets the image path dynamically (image located somewhere on disc rather than build as resource): 下面是一个动态设置图像路径的示例(图像位于光盘上的某个位置而不是构建为资源):
if (File.Exists(imagePath))
{
// Create image element to set as icon on the menu element
Image icon = new Image();
BitmapImage bmImage = new BitmapImage();
bmImage.BeginInit();
bmImage.UriSource = new Uri(imagePath, UriKind.Absolute);
bmImage.EndInit();
icon.Source = bmImage;
icon.MaxWidth = 25;
item.Icon = icon;
}
Reflections on Icons... 关于图标的思考......
First thought, you would think that the Icon property can only contain an image. 首先想到的是,你会认为Icon属性只能包含一个图像。 But it can actually contain anything! 但它实际上可以包含任何东西! I discovered this by accident when I programmatically tried to set the Image
property directly to a string with the path to an image. 当我以编程方式尝试将Image
属性直接设置为带有图像路径的字符串时,我偶然发现了这一点。 The result was that it did not show the image, but the actual text of the path! 结果是它没有显示图像,而是显示路径的实际文本!
This leads to an alternative to not have to make an image for the icon, but use text with a symbol font instead to display a simple "icon". 这导致了不必为图标制作图像的替代方案,而是使用带有符号字体的文本来显示简单的“图标”。 The following example uses the Wingdings font which contains a "floppydisk" symbol. 以下示例使用Wingdings字体 ,其中包含“floppydisk”符号。 This symbol is really the character <
, which has special meaning in XAML, so we have to use the encoded version <
这个符号实际上是字符<
,它在XAML中具有特殊含义,因此我们必须使用编码版本<
instead. 代替。 This works like a dream! 这就像一场梦! The following shows a floppydisk symbol as an icon on the menu item: 以下显示了一个floppydisk符号作为菜单项上的图标:
<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
<MenuItem.Icon>
<Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings"><</Label>
</MenuItem.Icon>
</MenuItem>
#3楼
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". 这将在名为“Images”的文件夹中加载一个名为“Untitled.png”的图像,其“Build Action”在名为“WpfApplication1”的程序集中设置为“Resource”。
#4楼
After having the same problem as you and doing some reading, I discovered the solution - Pack URIs . 在遇到与您相同的问题并进行一些阅读后,我发现了解决方案 - 包URI 。
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: 或更短,使用另一个BitmapImage构造函数:
finalImage.Source = new BitmapImage(
new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));
The URI is broken out into parts: URI分为几部分:
- Authority:
application:///
权限: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[;Version][;PublicKey];component/Path
- AssemblyShortName: the short name for the referenced assembly. AssemblyShortName:引用的程序集的简称。
- ;Version [optional]: the version of the referenced assembly that contains the resource file. ; Version [可选]:包含资源文件的引用程序集的版本。 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. ; PublicKey [可选]:用于对引用的程序集进行签名的公钥。 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. ; component:指定从本地程序集引用所引用的程序集。
- /Path: the name of the resource file, including its path, relative to the root of the referenced assembly's project folder. / Path:相对于引用程序集的项目文件夹的根目录的资源文件的名称,包括其路径。
The three slashes after application:
have to be replaced with commas: application:
后的三个斜线application:
必须用逗号替换:
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 "?" 注意:包URI的权限组件是指向包的嵌入式URI,必须符合RFC 2396.此外,“/”字符必须替换为“,”字符和保留字符,例如“%”和“?” must be escaped. 必须逃脱。 See the OPC for details. 有关详细信息,请参阅OPC。
And of course, make sure you set the build action on your image to Resource
. 当然,请确保将图像上的构建操作设置为Resource
。
#5楼
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;
#6楼
There's also a simpler way. 还有一种更简单的方法。 If the image is loaded as a resource in the XAML, and the code in question is the codebehind for that XAML: 如果图像作为资源加载到XAML中,并且有问题的代码是该XAML的代码隐藏:
Here's the resource dictionary for a XAML file - the only line you care about is the ImageBrush with the key "PosterBrush" - the rest of the code is just to show context 这是XAML文件的资源字典 - 你关心的唯一一行是带有“PosterBrush”键的ImageBrush - 其余代码只是为了显示上下文
<UserControl.Resources>
<ResourceDictionary>
<ImageBrush x:Key="PosterBrush" ImageSource="..\Resources\Images\EmptyPoster.jpg" Stretch="UniformToFill"/>
</ResourceDictionary>
</UserControl.Resources>
Now, in the code behind, you can just do this 现在,在后面的代码中,你可以这样做
ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"];