2008-12-07 155 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;