我的应用程序链接到类库(.dll)。在类库项目中,三个图像被放入Resources.resx中。需要在运行时选择一个图像并在按钮上显示。谷歌搜索后,我选择使用转换器来帮助xaml中的绑定:
[ValueConversion(typeof(Side), typeof(ImageSource))]
public class SideToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Side side = (Side)value;
switch (side)
{
case Side.Left:
return ToWpfBitmap(Properties.Resources.LeftArmOnCart);
case Side.Right:
return ToWpfBitmap(Properties.Resources.RightArmOnCart);
case Side.Both:
return ToWpfBitmap(Properties.Resources.RightArmOnCart);
default:
throw new ArgumentException("Current configuration is invalid");
}
}
private static BitmapSource ToWpfBitmap(Bitmap bitmap)
{
using (MemoryStream stream = new MemoryStream())
{
bitmap.Save(stream, ImageFormat.Png);
stream.Position = 0;
BitmapImage result = new BitmapImage();
result.BeginInit();
// According to MSDN, "The default OnDemand cache option retains access to the stream until the image is needed."
// Force the bitmap to load right now so we can dispose the stream.
result.CacheOption = BitmapCacheOption.OnLoad;
result.StreamSource = stream;
result.EndInit();
result.Freeze();
return result;
}
}
}
xaml代码看起来像
<Image Source="{Binding Side, Converter={StaticResource SideToImageConverter}}" .../>
不幸的是,图像不会在没有任何异常的情况下无声显示。调试转换器代码,ToWpfBitmap()中的位图参数看起来很好(宽度/高度值是正确的)。
BTW,作为另一个试验,以下代码工作正常。
[ValueConversion(typeof(Side), typeof(ImageSource))]
public class SideToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Side side = (Side)value;
switch (side)
{
case Side.Left:
return LoadBitmap("LeftArmOnCart.png");
case Side.Right:
return LoadBitmap("RightArmOnCart.png");
case Side.Both:
return LoadBitmap("RightArmOnCart.png");
default:
throw new ArgumentException("Current configuration is invalid");
}
}
private static BitmapSource LoadBitmap(string name)
{
BitmapImage result = new BitmapImage();
result.BeginInit();
string uri = "c:/.../Resources/Images/" + name;
result.CacheOption = BitmapCacheOption.OnLoad;
result.UriSource = new Uri(uri, UriKind.Absolute);
result.EndInit();
return result;
}
}
但是,不需要绝对路径。那么,我什么都错过了?
我知道通过释放三个图像文件来使用相对路径是可行的。但是,是否有可能不发布三个文件而只是类库dll?
谢谢!
答案 0 :(得分:0)
我认为您可以阅读一些内容来帮助解决您的问题。我将从Pack URIs in WPF开始,以便您了解如何使用URI检查特定库的位置。由于这些图像位于另一个程序集的资源文件中,因此请阅读&#34;参考资源程序集文件&#34;在链接中。
我认为值得一提的另一件事是两种方法之间的区别在于你提供UriSource
到(底部)和一种你没有(顶部)。查看Image.Source
,在XAML中使用时,它需要imageUri
。有了这个提示,我们可以说它肯定与URI有关。
事实上,您的图片已经保存为它们所在库中的流,因此我们不需要为创建新的位图或您正在做的任何事情做任何事情,而是我们可以简单地提供有效的包URI并返回一个字符串。
我认为这样的事情应该有效,前提是图像所在的库的名称是YourApp.Models
,在子文件夹Resources\Images\
中:
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
Side side = (Side)value;
switch (side)
{
case Side.Left:
return "pack://application:,,,/YourApp.Models;component/Resources/Images/LeftArmOnCart.png";
case Side.Right:
case Side.Both:
return "pack://application:,,,/YourApp.Models;component/Resources/Images/RightArmOnCart.png";
default:
throw new ArgumentException("Current configuration is invalid");
}
}
注意:路径名对前进/后退斜杠,程序集名称,组件敏感。确保所有内容都格式正确。
这被认为是绝对URI。相对URI只是"/Resources/Images/LeftArmOnCart.png"
,只有当该文件路径存在于调用它的程序集中时才会起作用 - 这意味着它不会为你工作,因为你从另一个程序集调用。 / p>
希望这有帮助!
答案 1 :(得分:0)
已经有一个InteropBitmap
类可用于将GDI位图转换为WPF ImageSource
,但我发现它不能很好地处理alpha通道。这是我使用的机制:
public static BitmapSource CreateBitmapSourceFromGdiBitmap(Bitmap bitmap)
{
if (bitmap == null)
throw new ArgumentNullException("bitmap");
var rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
var bitmapData = bitmap.LockBits(
rect,
ImageLockMode.ReadWrite,
PixelFormat.Format32bppArgb);
try
{
var size = (rect.Width * rect.Height) * 4;
return BitmapSource.Create(
bitmap.Width,
bitmap.Height,
bitmap.HorizontalResolution,
bitmap.VerticalResolution,
PixelFormats.Bgra32,
null,
bitmapData.Scan0,
size,
bitmapData.Stride);
}
finally
{
bitmap.UnlockBits(bitmapData);
}
}
请注意,此实现假定采用32bpp ARGB像素格式。如果您正在使用PNG图像,那应该没问题。否则,您需要添加转换步骤。