WPF图像资源

时间:2008-12-07 14:14:53

标签: c# .net wpf embedded-resource

我来自一个主要是网络和一点点Windows窗体背景。对于一个新项目,我们将使用WPF。 WPF应用程序需要10-20个小图标和图像用于说明目的。我正在考虑将它们作为嵌入式资源存储在程序集中。这是正确的方法吗?

如何在XAML中指定Image控件应该从嵌入式资源加载图像?

10 个答案:

答案 0 :(得分:452)

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

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

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

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

的内容
<Image Source="{StaticResource MyImageSource}" />

在我的情况下,我发现我必须将Image.png文件设置为Resource的构建操作,而不仅仅是Content。这会导致图像在编译的程序集中传输。

答案 1 :(得分:161)

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

  • 将文件“构建操作”更改为“内容”。请务必检查复制到构建目录
    • 在解决方案资源管理器窗口的“右键单击”菜单中找到。
  • 图像来源采用以下格式:
    • “/ «YourAssemblyName»;组件/«YourPath»/ «YourImage.png»

实施例

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

优点:

  • 文件未嵌入到程序集中。
    • 资源管理器会在资源过多的情况下(构建时)引发一些内存溢出问题。
  • 可以在程序集之间调用。

答案 2 :(得分:44)

有些人要求在代码中执行此操作而不是得到答案。

经过几个小时的搜索,我发现了一个非常简单的方法,我找不到任何例子,所以我在这里分享我的 适用于图像。 (我的是.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);
}

学习:

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

我希望这可以节省你希望这件作品给我的好几个小时!

答案 3 :(得分:39)

在代码中加载资源的执行程序集中我的图片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");

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

答案 4 :(得分:36)

是的,这是正确的方式。

您可以使用路径:

在资源文件中使用该图像
<Image Source="..\Media\Image.png" />

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

答案 5 :(得分:13)

完整说明如何使用资源: WPF Application Resource, Content, and Data Files

如何引用它们,请阅读“WPF中的包URI”。

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

答案 6 :(得分:4)

  1. Visual Studio 2010 Professional SP1。
  2. .NET Framework 4 Client Profile。
  3. PNG图片作为资源添加到项目属性中。
  4. 自动创建Resources文件夹中的新文件。
  5. 将操作设置为资源。
  6. 这对我有用:

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

答案 7 :(得分:3)

如果您正在使用Blend,为了使其更加轻松,并且在获取 Source 属性的正确路径时没有任何问题,只需从“项目”面板拖放图像即可到设计师身上。

答案 8 :(得分: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>

答案 9 :(得分:-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;