关于c#:WPF图像资源

WPF image resources

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

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


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

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

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

然后,在代码中,使用如下内容:

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

在我的例子中,我发现我必须设置Image.png文件来执行Resource的构建操作,而不仅仅是Content。这将导致图像在编译的程序集中被携带。


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

  • 将文件"构建操作"更改为"内容"。请确保选中"复制到生成目录"。
    • 在解决方案资源管理器窗口的"右键单击"菜单中找到。
  • 以下格式的图像源:
    • "?"你的名字?;组件/?你的路径??Yourimage.png?"

例子

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

好处:

小精灵小精灵文件未嵌入到程序集中。

  • 资源管理器将在资源过多的情况下(在构建时)引发一些内存溢出问题。
  • 不能在程序集之间调用。

  • 有些人在询问用代码来做这件事,却没有得到答案。

    在花了很多小时搜索之后,我找到了一个非常简单的方法,没有找到任何例子,所以我在这里分享了我的例子。与图像一起工作。(我的是.gif)

    总结:

    它返回图像源"目的地"似乎喜欢的位图帧。

    用途:

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

    方法:

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

    学习:

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

    我希望这能为你节省很多时间,我希望这件作品能带给我!


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

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

    我还做了一个功能:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    /// <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类中):

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

    注:参见wpf:pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml中的msdn pack uris。


    是的,这是正确的方法。

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

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

    必须将图像文件的生成操作设置为"资源"。


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

    以及如何引用它们,请阅读"在WPF中打包URI"。

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


  • Visual Studio 2010专业版SP1。
  • .NET Framework 4客户端配置文件。
  • 在项目属性中添加PNG图像作为资源。
  • "资源"文件夹中的新文件已自动创建。
  • 将生成操作设置为资源。
  • 这对我很有用:

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


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

    1
    2
    3
    4
    5
    <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>


    如果您使用的是Blend,为了使其更加容易,并且不存在任何问题,可以为源属性获取正确的路径,只需将图像从项目面板拖放到设计器中即可。


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

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