在代码中设置WPF图像源

我试图在代码中设置WPF图像的源代码。 该图像作为资源embedded到项目中。 通过查看示例,我已经提出了下面的代码。 由于某种原因,它不起作用 – 图像不显示。

通过debugging,我可以看到该stream包含图像数据。 那么怎么了?

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; 

图标定义如下: <Image x:Name="_icon" Width="16" Height="16" />

在遇到同样的问题并做了一些阅读之后,我发现了解决scheme – Pack URIs 。

我做了以下代码:

 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; 

或者更短,通过使用另一个BitmapImage构造函数:

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

URI被分解成部分:

  • 权限: application:///
  • path:编译到引用程序集的资源文件的名称。 该path必须符合以下格式: AssemblyShortName[;Version][;PublicKey];component/Path

    • AssemblyShortName:引用程序集的短名称。
    • ;版本[可选]:包含资源文件的引用程序集的版本。 当两个或多个引用的具有相同短名称的程序集被加载时使用。
    • ; PublicKey [可选]:用于签署引用程序集的公钥。 当两个或多个引用的具有相同短名称的程序集被加载时使用。
    • ; component:指定被引用的程序集是从本地程序集引用的。
    • /path:资源文件的名称,包括其path,相对于被引用程序集的项目文件夹的根目录。

application:后的三个斜杠application:必须用逗号代替:

注意:pack URI的权限组件是embedded的URI,指向一个包并且必须符合RFC 2396.另外,必须用“,”字符和保留字符(如“%”)replace“/”和“?” 必须逃脱。 有关详细信息,请参阅OPC。

当然,确保您将图像上的构build操作设置为“ Resource

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

这将在称为“图像”的文件夹中将名为“Untitled.png”的图像的“生成操作”设置为“资源”,名为“WpfApplication1”的程序集中。

这是less一点的代码,可以在一行中完成。

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

好简单:

要dynamic设置菜单项的图像,只需执行以下操作:

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

…而“icon.ico”可以位于任何地方(目前它位于“资源”目录中),并且必须链接为资源…

你有没有尝试过:

 Assembly asm = Assembly.GetExecutingAssembly(); Stream iconStream = asm.GetManifestResourceStream("SomeImage.png"); BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = iconStream; bitmap.EndInit(); _icon.Source = bitmap; 

你也可以把它减less到一行。 这是我用来为我的主窗口设置图标的代码。 它假定.ico文件被标记为内容并被复制到输出目录。

  this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative)); 

最简单的方法:

 var uriSource = new Uri("image path here"); image1.Source = new BitmapImage(uriSource); 

玩的开心 :)

以下是一个dynamic设置图像path的示例(图像位于光盘的某处,而不是构build为资源):

 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; } 

思考图标…

首先想到,你会认为Icon属性只能包含一个图像。 但它实际上可以包含任何东西! 当我以编程方式尝试将Image属性直接设置为具有图像path的string时,我意外发现了这一点。 结果是它没有显示图像,而是path的实际文本!

这导致了一种替代scheme,不必为图标制作图像,而是使用带有符号字体的文本来显示简单的“图标”。 以下示例使用包含“floppydisk”符号的Wingdings字体。 这个符号实际上是在XAML中具有特殊含义的字符< ,所以我们必须使用编码的版本&lt; 代替。 这工作像一个梦想! 下面在菜单项上显示一个floppydisk符号作为图标:

 <MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save"> <MenuItem.Icon> <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label> </MenuItem.Icon> </MenuItem> 

这是我的方式

 internal static class ResourceAccessor { public static Uri Get(string respurcePath) { var uri = string.Format( "pack://application:,,,/{0};component/{1}" , Assembly.GetExecutingAssembly().GetName().Name , respurcePath ); return new Uri(uri); } } 

用途:

 new BitmapImage(ResourceAccessor.Get("Images/1.png")) 

还有一个更简单的方法,如果图像被加载为xaml中的资源,并且所讨论的代码是该xaml的代码隐藏

 Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute); NotifyIcon.Icon = BitmapFrame.Create(iconUri); 

问候Bharat Thanki

将框架放在VisualBrush中:

 VisualBrush brush = new VisualBrush { TileMode = TileMode.None }; brush.Visual = frame; brush.AlignmentX = AlignmentX.Center; brush.AlignmentY = AlignmentY.Center; brush.Stretch = Stretch.Uniform; 

将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; 

现在把GeometryDrawing放在一个DrawingImage中:

 new DrawingImage(drawing); 

把它放在你的图像来源,等等!

你可以做得更容易,但是:

 <Image> <Image.Source> <BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage> </Image.Source> </Image> 

在代码中:

BitmapImage image = new BitmapImage {UriSource =“/ yourassembly; component / YourImage.PNG”};

HTH

还有一个更简单的方法,如果图像被加载为xaml中的资源,并且所讨论的代码是该xaml的代码隐藏

以下是XAML文件的资源字典 – 您唯一遇到的情况就是ImageBrush的关键字“PosterBrush” – 其余的代码只是为了显示上下文

 <UserControl.Resources> <ResourceDictionary> <ImageBrush x:Key="PosterBrush" ImageSource="..\Resources\Images\EmptyPoster.jpg" Stretch="UniformToFill"/> </ResourceDictionary> </UserControl.Resources> 

现在,在代码背后,你可以做到这一点

 ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"]; 

如果您的图像存储在ResourceDictionary中,则可以只使用一行代码:

 MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource; 

如何从资源图标和图像中加载embedded的图像(Arcturus的更正版本)

假设你想添加图像的button。 你该怎么办?
1.添加到项目文件夹图标,并把这里图片ClickMe.png
2.在“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

我是一个新的WPF,但不是在.NET中。 我花了5个小时尝试添加一个PNG文件到.NET 3.5(Visual Studio 2010)中的“WPF自定义控件Libyrary项目”,并将其设置为图像inheritance控件的背景。

没有任何与URI相关的工作。 我无法想象为什么没有从资源文件中获取URI的方法,例如IntelliSense,也许是:

 Properties.Resources.ResourceManager.GetURI("my_image"); 

我已经尝试了很多的URI,并使用ResourceManager和Assembly的GetManifest方法,但在所有的地方都有exception或NULL值。

在这里,我为我工作的代码:

 // 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; 

如果你已经有一个stream,并知道格式,你可以使用这样的东西:

 static ImageSource PngStreamToImageSource (Stream pngStream) { var decoder = new PngBitmapDecoder(pngStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default); return decoder.Frames[0]; } 

你只是错过了一点点。

为了从任何程序集中获得embedded式资源,你必须提及程序集名称和你的文件名,正如我在这里提到的那样。

 Assembly asm = Assembly.GetExecutingAssembly(); Stream iconStream = asm.GetManifestResourceStream(asm.GetName().Name + "." + "Desert.jpg"); BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = iconStream; bitmap.EndInit(); image1.Source = bitmap;