C# 在代码中设置 WPF 图片源
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/350027/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Setting WPF image source in code
提问by Torbj?rn
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.
我正在尝试在代码中设置 WPF 图像的源。图像作为资源嵌入到项目中。通过查看示例,我想出了以下代码。由于某种原因它不起作用 - 图像不显示。
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" />
采纳答案by Jared Harley
After having the same problem as you and doing some reading, I discovered the solution - Pack URIs.
在遇到与您相同的问题并进行一些阅读后,我发现了解决方案 - 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:
或者更短,通过使用另一个 BitmapImage 构造函数:
finalImage.Source = new BitmapImage(
new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));
The URI is broken out into parts:
URI 分为几个部分:
- 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.
- 权威:
application:/// 路径:编译为引用程序集的资源文件的名称。路径必须符合以下格式:
AssemblyShortName[;Version][;PublicKey];component/Path- AssemblyShortName:引用程序集的短名称。
- ;Version [可选]:包含资源文件的引用程序集的版本。当加载两个或多个具有相同短名称的引用程序集时使用。
- ;PublicKey [可选]:用于对引用的程序集进行签名的公钥。当加载了两个或多个具有相同短名称的引用程序集时使用。
- ;component:指定被引用的程序集是从本地程序集引用的。
- /Path:资源文件的名称,包括其路径,相对于引用程序集的项目文件夹的根目录。
The three slashes after application:have to be replaced with commas:
后面的三个斜杠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 "?" must be escaped. See the OPC for details.
注意:包 URI 的授权组件是指向包的嵌入 URI,必须符合 RFC 2396。此外,“/”字符必须替换为“,”字符,以及“%”等保留字符和 ”?” 必须逃脱。有关详细信息,请参阅 OPC。
And of course, make sure you set the build action on your image to Resource.
当然,请确保将图像上的构建操作设置为Resource.
回答by Arcturus
Put the frame in a VisualBrush:
将框架放在 VisualBrush 中:
VisualBrush brush = new VisualBrush { TileMode = TileMode.None };
brush.Visual = frame;
brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;
Put the VisualBrush in GeometryDrawing
将 VisualBrush 放入 GeometryDrawing
GeometryDrawing drawing = new GeometryDrawing();
drawing.Brush = brush;
// Brush this in 1, 1 ratio
RectangleGeometry rect = new RectangleGeometry { Rect = new Rect(0, 0, 1, 1) };
drawing.Geometry = rect;
Now put the GeometryDrawing in a DrawingImage:
现在将 GeometryDrawing 放在 DrawingImage 中:
new DrawingImage(drawing);
Place this on your source of the image, and voilà!
把它放在你的图像来源上,瞧!
You could do it a lot easier though:
不过,您可以更轻松地做到这一点:
<Image>
<Image.Source>
<BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
</Image.Source>
</Image>
And in code:
在代码中:
BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };
回答by Andrew Myhre
Have you tried:
你有没有尝试过:
Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
回答by awe
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. But it can actually contain anything! I discovered this by accident when I programmatically tried to set the Imageproperty directly to a string with the path to an image. The result was that it did not show the image, but the actual text of the path!
首先想到的是,您会认为 Icon 属性只能包含一个图像。但它实际上可以包含任何东西!当我以编程方式尝试将Image属性直接设置为带有图像路径的字符串时,我偶然发现了这一点。结果是它没有显示图像,而是路径的实际文本!
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 fontwhich contains a "floppydisk" symbol. This symbol is really the character <, which has special meaning in XAML, so we have to use the encoded version <instead. This works like a dream! The following shows a floppydisk symbol as an icon on the menu item:
这导致不必为图标制作图像,而是使用带有符号字体的文本来显示简单的“图标”。以下示例使用包含“软盘”符号的Wingdings 字体。这个符号实际上是字符<,它在 XAML 中具有特殊含义,因此我们必须改用编码版本<。这就像做梦一样!下面将软盘符号显示为菜单项上的图标:
<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
<MenuItem.Icon>
<Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings"><</Label>
</MenuItem.Icon>
</MenuItem>
回答by Simon
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”的图像,在名为“WpfApplication1”的程序集中,其“构建操作”设置为“资源”。
回答by Alex B
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;
回答by Mark Mullin
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"];
回答by Siarhei Kuchuk
How to load an image from embedded in resource icons and images (corrected version of Arcturus):
如何从嵌入的资源图标和图像中加载图像(Arcturus 的修正版本):
Suppose you want to add a button with an image. What should you do?
假设您要添加一个带有图像的按钮。你该怎么办?
- Add to project folder icons and put image ClickMe.png here
- In properties of 'ClickMe.png', set 'BuildAction' to 'Resource'
- Suppose your compiled assembly name is 'Company.ProductAssembly.dll'.
Now it's time to load our image in XAML
<Button Width="200" Height="70"> <Button.Content> <StackPanel> <Image Width="20" Height="20"> <Image.Source> <BitmapImage UriSource="/Company.ProductAssembly;component/Icons/ClickMe.png"></BitmapImage> </Image.Source> </Image> <TextBlock HorizontalAlignment="Center">Click me!</TextBlock> </StackPanel> </Button.Content> </Button>
- 添加到项目文件夹图标并将图像 ClickMe.png 放在这里
- 在“ClickMe.png”的属性中,将“BuildAction”设置为“Resource”
- 假设您编译的程序集名称是“Company.ProductAssembly.dll”。
现在是时候在 XAML 中加载我们的图像了
<Button Width="200" Height="70"> <Button.Content> <StackPanel> <Image Width="20" Height="20"> <Image.Source> <BitmapImage UriSource="/Company.ProductAssembly;component/Icons/ClickMe.png"></BitmapImage> </Image.Source> </Image> <TextBlock HorizontalAlignment="Center">Click me!</TextBlock> </StackPanel> </Button.Content> </Button>
Done.
完毕。
回答by Siarhei Kuchuk
If you already have a stream and know the format, you can use something like this:
如果你已经有一个流并且知道格式,你可以使用这样的东西:
static ImageSource PngStreamToImageSource (Stream pngStream) {
var decoder = new PngBitmapDecoder(pngStream,
BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
return decoder.Frames[0];
}
回答by JoanComasFdz
I am a new to WPF, but not in .NET.
我是 WPF 的新手,但不是 .NET。
I have spent five hours trying to add a PNG file to a "WPF Custom Control Library Project" in .NET 3.5 (Visual Studio 2010) and setting it as a background of an image-inherited control.
我花了五个小时试图将 PNG 文件添加到 .NET 3.5 (Visual Studio 2010) 中的“WPF 自定义控件库项目”,并将其设置为图像继承控件的背景。
Nothing relative with URIs worked. I can not imagine why there is no method to get a URI from a resource file, through IntelliSense, maybe as:
没有任何与 URI 相关的工作。我无法想象为什么没有通过 IntelliSense 从资源文件中获取 URI 的方法,可能是:
Properties.Resources.ResourceManager.GetURI("my_image");
I've tried a lot of URIs and played with ResourceManager, and Assembly's GetManifest methods, but all there were exceptions or NULL values.
我已经尝试了很多 URI 并使用了 ResourceManager 和 Assembly 的 GetManifest 方法,但都存在异常或 NULL 值。
Here I pot the code that worked for me:
在这里,我编写了对我有用的代码:
// Convert the image in resources to a Stream
Stream ms = new MemoryStream()
Properties.Resources.MyImage.Save(ms, ImageFormat.Png);
// Create a BitmapImage with the stream.
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();
// Set as source
Source = bitmap;

