439

对于需要 10 到 20 个小图标和图像用于说明目的的 WPF 应用程序,将这些作为嵌入式资源存储在程序集中是正确的方法吗?

如果是这样,我如何在 XAML 中指定 Image 控件应从嵌入式资源加载图像?

4

10 回答 10

498

如果您将在多个地方使用图像,那么值得将图像数据仅加载一次到内存中,然后在所有Image元素之间共享它。

为此,请BitmapSource 在某处创建一个资源:

<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />

然后,在您的代码中,使用类似:

<Image Source="{StaticResource MyImageSource}" />

就我而言,我发现我必须将Image.png文件设置为具有构建操作,Resource而不仅仅是Content. 这会导致图像在您编译的程序集中携带。

于 2009-03-03T16:02:33.630 回答
195

我发现使用图像、视频等的最佳做法是:

  • 将您的文件“构建操作”更改为“内容”。请务必选中Copy to build directory
    • 在解决方案资源管理器窗口的“右键单击”菜单中找到。
  • 图像源格式如下:
    • "/ «YourAssemblyName» ;component/«YourPath»/ «YourImage.png» "

例子

<Image Source="/WPFApplication;component/Images/Start.png" />

好处:

  • 文件不会嵌入到程序集中。
    • 资源管理器将引发一些资源过多的内存溢出问题(在构建时)。
  • 可以在程序集之间调用。
于 2010-03-10T11:32:28.160 回答
49

有些人在询问是否在代码中执行此操作,但没有得到答案。

在花了很多时间搜索之后,我找到了一个非常简单的方法,但我没有找到示例,所以我在这里分享我的适用于图像的方法。(我的是.gif)

概括:

它返回 ImageSource“目的地”似乎喜欢的 BitmapFrame。

采用:

doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");

方法:

static internal ImageSource doGetImageSourceFromResource(string psAssemblyName, string psResourceName)
{
    Uri oUri = new Uri("pack://application:,,,/" +psAssemblyName +";component/" +psResourceName, UriKind.RelativeOrAbsolute);
    return BitmapFrame.Create(oUri);
}

学习:

根据我的经验,包字符串不是问题,请检查您的流,特别是如果第一次读取它已将指针设置为文件末尾并且您需要在再次读取之前将其重新设置为零。

我希望这可以为您节省很多时间,我希望这件作品对我有用!

于 2011-02-13T16:49:45.760 回答
47

在代码中加载执行程序集中的资源,其中我的图像Freq.png位于文件夹中Icons并定义为Resource

this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/" 
    + Assembly.GetExecutingAssembly().GetName().Name 
    + ";component/" 
    + "Icons/Freq.png", UriKind.Absolute)); 

我还做了一个功能:

/// <summary>
/// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
/// </summary>
/// <param name="pathInApplication">Path without starting slash</param>
/// <param name="assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling assembly</param>
/// <returns></returns>
public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
{
    if (assembly == null)
    {
        assembly = Assembly.GetCallingAssembly();
    }

    if (pathInApplication[0] == '/')
    {
        pathInApplication = pathInApplication.Substring(1);
    }
    return new BitmapImage(new Uri(@"pack://application:,,,/" + assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute)); 
}

用法(假设您将函数放在 ResourceHelper 类中):

this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");

注意:请参阅WPF 中的 MSDN Pack URI
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

于 2012-03-16T13:15:56.720 回答
45

是的,这是正确的方法。

您可以仅使用路径在资源文件中使用图像:

<Image Source="..\Media\Image.png" />

您必须将映像文件的构建操作设置为“资源”。

于 2008-12-07T17:34:29.843 回答
14

完整描述如何使用资源:WPF 应用程序资源、内容和数据文件

以及如何引用它们,请阅读“Pack URIs in WPF”。

简而言之,甚至可以通过引用/引用程序集引用资源。

于 2010-04-13T19:12:08.187 回答
7
  1. Visual Studio 2010 专业版 SP1。
  2. .NET Framework 4 客户端配置文件。
  3. 在项目属性中添加为资源的 PNG 图像。
  4. 资源文件夹中的新文件自动创建。
  5. 将操作设置为资源。

这对我有用:

<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />
于 2011-08-23T09:16:51.013 回答
3

如果您使用的是Blend,为了使其更加简单并且在获取Source属性的正确路径时不会遇到任何问题,只需将图像从“项目”面板拖放到设计器上。

于 2008-12-07T23:52:15.977 回答
3

是的,这是正确的方法。您可以使用路径在资源文件中使用图像:

<StackPanel Orientation="Horizontal">
    <CheckBox  Content="{Binding Nname}" IsChecked="{Binding IsChecked}"/>
    <Image Source="E:\SWorking\SharePointSecurityApps\SharePointSecurityApps\SharePointSecurityApps.WPF\Images\sitepermission.png"/>
    <TextBlock Text="{Binding Path=Title}"></TextBlock>
</StackPanel>
于 2018-04-24T10:47:37.907 回答
-4

以下工作并且要设置的图像是属性中的资源:

    var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
                                      IntPtr.Zero,
                                      Int32Rect.Empty,
                                      BitmapSizeOptions.FromEmptyOptions());
    MyButton.Background = new ImageBrush(bitmapSource);
img_username.Source = bitmapSource;
于 2015-01-08T23:04:35.847 回答