WPF图像资源

dri*_*iis 392 .net c# wpf embedded-resource

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

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

Dre*_*kes 463

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

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

<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />
Run Code Online (Sandbox Code Playgroud)

然后,在您的代码中,使用以下内容:

<Image Source="{StaticResource MyImageSource}" />
Run Code Online (Sandbox Code Playgroud)

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

  • 我点击的内容:如果您将图像资源添加到资源字典中,请不要忘记在XAML中为您的组件引用该图像字典.类似于:<UserControl.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source ="Dictionary1.xaml"/> </ ResourceDictionary.MergedDictionaries> </ ResourceDictionary> </ UserControl.Resources> (8认同)
  • 有可能动态地这样做吗?如果我想在启动时加载不同数量的图像,我可以为每个图像创建一个BitmapSource并以与上面相同的方式引用它们吗? (5认同)
  • 我通常会将`Width ="{Binding Source.PixelWidth,RelativeSource = {RelativeSource Self}}"`添加到`Image`中,否则我经常会看到由于某种原因(例如16x16图标被拉伸到某个原因)看起来像200x200像素). (4认同)
  • 我发现如果在引用的程序集的resourcedictionary中声明了BitmapImage,则UriSource需要是一个packURI才能使其工作.否则,您会发现在VS中的xaml编辑器中可以看到图像,但在调试时没有图像.Pack URIS:https://msdn.microsoft.com/en-au/library/aa970069(v = vs.100).aspx (3认同)
  • @Becky - 是的,你可以,但是如果你想在Xaml中引用它们那么你可能需要使用`DynamicResource`标记扩展而不是`StaticResource`,假设你在编译时知道密钥.在WPF中,您可以在运行时创建资源字典.实际上,这就是加载Xaml文档时会发生的情况,只是你没有看到等效的C#. (2认同)

Nun*_*ues 168

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

  • 将文件"构建操作"更改为"内容".请务必选中复制到构建目录.
    • 在Solution Explorer窗口的"右键单击"菜单中找到.
  • 图像源采用以下格式:
    • "/ «YourAssemblyName» ;组件/«YourPath»/«YourImage.png» "

<Image Source="/WPFApplication;component/Images/Start.png" />
Run Code Online (Sandbox Code Playgroud)

优点:

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

  • 如果将资源嵌入到程序集中,则此方法也适用,但您必须将"构建操作"设置为"资源". (33认同)
  • 工作,谢谢.另一个注意事项:"组件"是"按原样","图像"是项目中png的相对路径.即放在根目录中的图像将是"<Image Source ="/ WPFApplication; component/Start.png"/>" (5认同)
  • 那么,如果文件设置为嵌入式资源,您如何做?这似乎不起作用.而且我不想将图像包含在我的项目中两次.(我已经将它用作嵌入式资源.) (4认同)
  • 如何在C#中执行此操作的示例将很好.(这不是有效的URI,因此在构造BitmapImage时无法使用它.) (3认同)
  • “组件”在哪里以及如何进入路径。那是某些规范的一部分吗? (2认同)

小智 46

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

经过几个小时的搜索,我找到了一个非常简单的方法,我找不到任何例子,所以我在这里分享我的图像.(我的是.gif)

摘要:

它返回一个ImageSource"目的地"似乎喜欢的BitmapFrame.

使用:

doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");
Run Code Online (Sandbox Code Playgroud)

方法:

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

学习:

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

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


Eri*_*let 41

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

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

我也做了一个功能:

/// <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)); 
}
Run Code Online (Sandbox Code Playgroud)

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

this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");
Run Code Online (Sandbox Code Playgroud)

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


ema*_*ema 39

是的,这是正确的方式.

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

<Image Source="..\Media\Image.png" />
Run Code Online (Sandbox Code Playgroud)

您必须将映像文件的构建操作设置为"资源".

  • 当您需要重构代码时,这将是一团糟.如果xaml文档碰巧更改名称空间,则必须手动更改所有图像引用.Drew Noakes描述的方法更加顺畅和易于维护. (2认同)

tec*_*fan 13

完整说明如何使用资源:WPF应用程序资源,内容和数据文件

以及如何引用它们,请阅读"WPF中的包URI".

简而言之,甚至还有从引用/引用程序集引用资源的方法.


Joa*_*Fdz 5

  1. Visual Studio 2010专业版SP1。
  2. .NET Framework 4客户端配置文件。
  3. PNG图像作为项目属性的资源添加。
  4. 资源文件夹中的新文件会自动创建。
  5. 将操作设置为资源。

这为我工作:

<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />
Run Code Online (Sandbox Code Playgroud)