我正在开发一个Windows窗体应用程序,我将使用多组图像(想想图标)。根据主题,必须选择不同的图像集(我稍后将使用Bitmap
绘制它们。)
我在考虑将图像存储在单独的文件中(存档文件?dll?),然后在运行时从主应用程序加载它们。最有效的方法是什么?
感谢您的阅读。
答案 0 :(得分:3)
我会在几个场景中回答这个问题。
此图片经常更改吗?然后转到基于目录的approcach,将其存储在目录中并加载它。也许你可以拥有一个xml来加载这些文件的名称。因此,在文件(图像)中更改名称,只需更改xml。
这些文件永远不会改变?然后只是将它们作为资源嵌入,这种方式将嵌入到你的exe / dll中,没有人可以破坏图像。
通常我见过人们没有嵌入。
答案 1 :(得分:0)
您是否考虑过使用resx文件(资源文件)?这样,您可以嵌入任何图像(图标)或任何您喜欢的图像,并决定仅加载基于您的主题所需的资源文件(资源文件可以根据您的主题名称命名)。似乎在本地化时遇到同样的问题,不是吗?但是要知道它是否是最佳方式(性能,记忆等),我无法分辨。
答案 2 :(得分:0)
不确定你是否得到了你想要的答案。以下是创建资源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>
。通常,您只有一个,但使用此方法您还可以托管多组资源,并在同一资源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);
}