在我的C#项目中,我有一个图像列表,这些图像是在exe中编译的资源:
/Pics/Image1.png
/Pics/Image2.png
/Pics/Image3.png
...
在我的代码中,我处理图像以使其与应用程序的主题匹配。我遇到的问题是,我试图找出一种简单的方法来以XAML语法访问这些已处理的图像。
这通常是我访问资源图像(预处理)的方式:
<Image Source="/Pics/Image1.png" />
所以我真的很想以类似的方式访问这些处理过的图像。
我尝试过这样的静态字典:
<Image Source="{x:Static local:Theme.Images.ImageDictionary[/Pics/Image1.png]}" />
但是这引发了一个错误,因为它不喜欢“ .png”,我还无法使用字典键来实现。更不用说这看起来真的很丑。
理想情况下,我希望能够“替换”资源引用,或在运行时创建资源(例如PicsProcessed/Image1.png
),但一直无法找到一种在运行中添加或修改资源的方法通过编程C#应用程序。
任何建议都非常感谢-谢谢!
答案 0 :(得分:0)
您是否尝试过创建Bitmap
并将其设置为图像source
?我认为这应该很容易。给图片起个名字,例如theImage
。您不能在未命名的情况下引用该图像。
请尝试以下操作:
string path="/Pics/Image3.png";//path to the image
var bitmapImage=new Bitmap(new Uri(path));
theImage.source=bitmapImage;//set the bitmap as the source.
不过,还有其他方法可以实现此目的。希望这会有所帮助吗?
答案 1 :(得分:0)
过了几天,但我想出了解决方案!
在相同的解决方案中,我将所有图像移到了另一个C#项目中,并设置为作为类库DLL文件进行编译,该文件名为DynamicResources.dll(“项目”设置中的程序集名称为“ DynamicResources”)。该项目被添加为对主项目的引用。这样,我可以在XAML中访问图像-整洁:
<Image Source="/DynamicResources;component/pics/image1.png" />
然后在主项目的构建后事件中,我重命名已编译的.dll,以便它在启动时不会被主.exe二进制文件加载:
copy "$(TargetDir)DynamicResources.dll" "$(TargetDir)DynamicResources.temp"
del "$(TargetDir)DynamicResources.dll"
然后,我使用了一个名为Mono.Cecil的第三方库来加载DynamicResources.temp文件(DLL格式),替换资源,将其写回到内存中,然后告诉应用程序进行加载:
public static void UpdateAssembly()
{
string dllFile = "DynamicResources.temp";
string dllNamespace = "DynamicResources";
var asm = AssemblyDefinition.ReadAssembly(dllFile);
var module = asm.Modules.FirstOrDefault();
var resources = module.Resources;
var dllResource = (EmbeddedResource)(resources.FirstOrDefault());
var dllResourceReader = new ResourceReader(dllResource.GetResourceStream());
var newResourceOutputStream = new MemoryStream();
var newResourceWriter = new ResourceWriter(newResourceOutputStream);
foreach (DictionaryEntry dllResourceEntry in dllResourceReader)
{
var image = (BitmapSource)new ImageSourceConverter().ConvertFrom(dllResourceEntry.Value);
Color foreground = (Color)ColorConverter.ConvertFromString("#FFFFFF");
var processed = (WriteableBitmap)ColorizeImage(image, foreground); // Your image processing function ?
newResourceWriter.AddResource(dllResourceEntry.Key.ToString(), BitmapToByte(processed));
}
newResourceWriter.Close();
var newResource = new EmbeddedResource(dllResource.Name, dllResource.Attributes, newResourceOutputStream.ToArray());
module.Resources.Remove(dllResource);
module.Resources.Add(newResource);
var woutput = new MemoryStream();
asm.Write(woutput);
var doutput = woutput.ToArray();
Assembly assembly = Assembly.Load(doutput);
}
public static MemoryStream BitmapToByte(BitmapSource bitmapSource)
{
var encoder = new System.Windows.Media.Imaging.PngBitmapEncoder();
var frame = System.Windows.Media.Imaging.BitmapFrame.Create(bitmapSource);
encoder.Frames.Add(frame);
var stream = new MemoryStream();
encoder.Save(stream);
return stream;
}
public static void AttachAssembly(string myAsmFileName)
{
Assembly assembly = Assembly.LoadFile(AppDomain.CurrentDomain.BaseDirectory + myAsmFileName); // LoadFrom
AppDomain.CurrentDomain.Load(assembly.GetName());
}
重要说明:遍历资源时,它们变为小写,因此您必须使用小写的文件名和文件夹名。