簡體   English   中英

為Windows窗體存儲圖像集的最佳方法

[英]Best way to store sets of images for Windows Forms

我正在開發Windows窗體應用程序,我將使用圖像集(如圖標)。 根據主題,必須選擇不同的圖像集(我稍后將使用Bitmap繪制它們)。

我當時正在考慮將圖像存儲在單獨的文件(存檔文件dll)中,然后在運行時從主應用程序加載它們。 什么是最有效的方法呢?

謝謝你的閱讀。

考慮幾種情況,我將回答這個問題。

  1. 該圖像是否經常更改? 然后使用基於目錄的方法,將其存儲在目錄中並加載。 可能是您可以包含要加載的這些文件的名稱的xml。 因此,在文件(圖像)中更改名稱,只需更改xml。

  2. 這些文件永遠不會改變? 然后只需將它們作為資源嵌入,這樣就可以將其嵌入到您的exe / dll中,並且不會破壞圖像。

通常我看到人們沒有做嵌入。

您是否考慮過使用resx文件(資源文件)? 這樣,您可以嵌入任何圖像(圖標)或任何您喜歡的圖像,並決定僅加載基於主題的所需資源文件(可以根據主題名稱命名資源文件)。 本地化時似乎遇到了同樣的問題,不是嗎? 但是要知道這是否是最好的方法(性能,內存等),我無法確定。

不知道您是否正在尋找答案。 這是創建資源dll的分步說明

  1. 在Visual Studio,類庫中創建一個新項目
  2. 將您的資源(圖片)添加到項目中(添加現有項目)
  3. 對於每個資源,在屬性窗口中,將“構建操作”設置為“嵌入式資源”。
  4. 編譯庫,生成一個dll
  5. 在您的winforms應用程序中,您現在可以在運行時加載此程序集(代碼1)
  6. 加載所需的資源流並將其保存到位圖對象(代碼2)

代碼#1

Assembly ambly = Assembly.LoadFile(pathToDll);

代碼#2

BitMap bitMap;
// where "ns" is the default namespace of the resource project    
using (Stream resourceStream = ambly.GetManifestResourceSream("ns.image.jpg"))
{
      bitMap = BitMap.FromStream(resourceStream);
}

這些是用於嵌入資源並在運行時加載資源的基本技術。

現在,由於您正在考慮使用不同的主題,並且將每個主題的資源存儲在不同的庫中,因此您應該有一個接口,該接口指定在主應用程序中定義的某種資源管理器。

一個例子

interface IThemeResourceProvider
{
     Stream LoadBigLogo();
     Stream LoadSmallLogo();
} 

然后在您的資源庫中實現該接口

public class ThemeResourceProvider : IThemeResourceProvider
{
    public Stream LoadBigLogo()
    {
         Assembly ambly = Assembly.GetExecutingAssembly();
         return ambly.GetManifestResourceStream("namespace.image.jpg");
    }

    (...)
}

最后,您可以實例化在資源庫中找到的IThemeResourceProvider,而不是直接在主應用程序中加載資源。

 Assembly assembly = Assembly.LoadFile(pathToDll);

 var results = from type in assembly.GetTypes()
               where typeof(IThemeResourceProvider).IsAssignableFrom(type)
               select type;

現在,該列表中有一個IEnumerable<Type> 通常,您只有一個,但是使用這種方法,您還可以托管多組資源,並在同一資源dll中實現多個IThemeResourceProviders。 例如,您可以使用名稱標識每個IThemeResourceProvider,將其作為屬性,或在各種實現中使用自定義的[Attribute]裝飾。 我把剩下的交給你去解決。

但是,這是在您的列表中實例化IThemeResourceProviders的方法

foreach (var providerType in results)
{
     var constructorInfo = providerType.GetConstructor(Type.EmptyTypes);
     IThemeResourceProvider provider = constructorInfo.Invoke(null);
}

最后,使用以下提供程序之一獲取位圖:

BitMap bitMap;
using (Stream resourceStream = provider.LoadBigLogo())
{
      bitMap = BitMap.FromStream(resourceStream);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM