2008-12-07 142 views
356

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

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

回答

421

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

要做到这一点,创建一个BitmapSource作为地方资源:

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

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

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

以我为例,我发现,我不得不将Image.png文件设置为具有Resource的构建操作,而不是Content。这会导致图像被载入您的编译程序集。

+5

是否可以动态地做到这一点?如果我想要在启动时加载不同数量的图像,是否可以为每个图像创建一个BitmapSource并以与上述相同的方式引用它们? – 2010-08-04 13:15:07

+2

@Becky - 是的,你可以,但如果你想指他们在XAML,那么你可能需要使用`DynamicResource`标记扩展,而不是`StaticResource`,假设你会知道在编译时的关键。在WPF中,您可以在运行时创建资源字典。事实上,当你加载一个Xaml文档时会发生这种情况,只是你没有看到相应的C#。 – 2010-08-04 14:21:53

+0

感谢您的答复:)我会通过FindResource可以指的他们,但我认为这可以节省处理的荒谬量在我的应用程序现在这么谢谢:) – 2010-08-05 07:48:47

34

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

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

如果你使用的混合必须设置图像文件的“资源”

+1

谢谢你。有没有办法像ImageSource做类似的事情,本质上是将图像加载到资源字典中。我担心这种方法会在内存中加载多次图像数据。 – 2009-03-03 14:31:42

+2

当你需要重构你的代码时,这将是一团糟。如果您的xaml文档恰好改变命名空间,您将不得不手动更改所有图像引用。 Drew Noakes描述的方法更加流畅和可维护。 – 2009-11-08 18:32:28

2

的累积作用,使它特别容易,并且没有任何问题为Source属性获取正确的路径,只需将图像从“项目”面板拖放到设计器上即可。

150

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

  • 更改文件“建设行动”“内容”。一定要检查复制到构建目录在解决方案资源管理器窗口按以下格式
  • 图像源的“右键单击”菜单上找到
      • “/ « YourAssemblyName»;组件/«您的路径»/ «YourImage。PNG»

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

    优点:

    • 的文件不被嵌入到装配
      • 资源管理器将提出一些内存溢出亲有太多的资源blems(在编译的时候)
    • 可以称为组件之间
  • 41

    有些人询问有关代码实现这一点并没有得到一个ANSW参考资源呃。

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

    摘要:

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

    用途:

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

    学习:

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

    我希望这可以节省你很多小时,我希望这件作品对我来说!

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

    这为我工作:

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

    在代码中executiong组件加载资源在那里我的形象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

    这个工作

    和图像设置为资源在属性

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