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

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


当前回答

在代码中加载执行程序集中的资源,其中我的图像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包uri: Pack://application:…/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

其他回答

在代码中加载执行程序集中的资源,其中我的图像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包uri: Pack://application:…/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

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

要做到这一点,在某处创建一个BitmapSource作为资源:

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

然后,在你的代码中,使用如下代码:

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

在我的例子中,我发现我必须将Image.png文件设置为资源而不仅仅是内容的构建操作。这将导致在已编译程序集中携带映像。

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

将文件的“构建动作”改为“内容”。请务必勾选“复制到构建目录”。 在“解决方案资源管理器”窗口的“右键单击”菜单中找到。 图片来源格式如下: “/«YourAssemblyName»;组件/«YourPath»和«YourImage.png»”

例子

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

好处:

文件没有嵌入到程序集中。 资源管理器会因为太多的资源(在构建时)而引发一些内存溢出问题。 可以在程序集之间调用。

有些人问在代码中这样做,但没有得到答案。

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

简介:

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

Use:

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

经验:

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

我希望这能节省你很多时间,我希望这篇文章为我!

下面工作和待设置的图像是在属性中的资源:

    var bitmapSource = Imaging.CreateBitmapSourceFromHBitmap(MyProject.Properties.Resources.myImage.GetHbitmap(),
                                      IntPtr.Zero,
                                      Int32Rect.Empty,
                                      BitmapSizeOptions.FromEmptyOptions());
    MyButton.Background = new ImageBrush(bitmapSource);
img_username.Source = bitmapSource;