私は Windows フォーム アプリケーションを開発しており、一連の画像 (アイコンと考えてください) を使用します。テーマに応じて、さまざまな画像セットを選択する必要があります (後で を使用して描画しますBitmap
)。
画像を別のファイル (アーカイブ ファイル? dll?) に保存し、実行時にメイン アプリケーションから読み込むことを考えていました。これを行う最も効果的な方法は何ですか?
読んでくれてありがとう。
私は Windows フォーム アプリケーションを開発しており、一連の画像 (アイコンと考えてください) を使用します。テーマに応じて、さまざまな画像セットを選択する必要があります (後で を使用して描画しますBitmap
)。
画像を別のファイル (アーカイブ ファイル? dll?) に保存し、実行時にメイン アプリケーションから読み込むことを考えていました。これを行う最も効果的な方法は何ですか?
読んでくれてありがとう。
いくつかのシナリオを考慮して、これに答えます。
この画像は頻繁に変更されますか? 次に、ディレクトリベースのアプローチに進み、ディレクトリに保存してロードします。ロードするこれらのファイルの名前を持つ xml を持つことができるかもしれません。ファイル(画像)の名前を変更するので、xmlを変更するだけです。
これらのファイルは変更されませんか? 次に、それらをリソースとして埋め込むだけで、exe / dllに埋め込まれ、画像が破損することはありません。
通常、埋め込みを行っていない人を見てきました。
resxファイル(リソースファイル)の使用を考えましたか?このようにして、任意の画像(アイコン)または好きなものを埋め込んで、テーマに基づいて必要なリソースファイルのみをロードすることを決定できます(リソースファイルにはテーマ名に基づいて名前を付けることができます)。ローカライズ時に発生したのと同じ問題のようですね。しかし、それが最善の方法(パフォーマンス、メモリなど)であるかどうかを知るには、わかりません。
探していた答えが得られたかどうかはわかりません。リソース dll を作成する手順は次のとおりです。
コード#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>
で、そのリストに があります。通常は 1 つしかありませんが、このアプローチを使用すると、複数のリソース セットをホストし、同じリソース dll に複数の IThemeResourceProvider を実装することもできます。たとえば、プロパティとして、または[Attribute]
さまざまな実装でカスタム装飾を使用して、各 IThemeResourceProvider を名前で識別することができます。残りはあなたに任せます。
ただし、リストで 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);
}