如何在运行时将图像加载到WPF?

24

看起来在 WPF 窗口中运行时加载图像相当复杂。

Image image;
image = new Uri("Bilder/sas.png", UriKind.Relative);
????.Source = new BitmapImage(image);

我正在尝试这段代码,但是我需要一些帮助才能让它正常工作。在代码下面出现了一些红线!我还想知道我是否需要在XAML代码中添加一些额外的代码,还是只需要这个就足够了:

<Image Height="200" HorizontalAlignment="Left" Margin="12,12,0,0" Name="image1" 
       Stretch="Fill" VerticalAlignment="Top" Width="350" />

我想知道为什么有些示例将图像的源放在XAML标记内部。

编辑:

我现在正在使用以下代码:

var uri = new Uri("pack://application:,,,/sas.png");
var bitmap = new BitmapImage(uri);
image1.Source = bitmap;

XAML:

<Grid Width="374">
    <Image Height="200" HorizontalAlignment="Left" Margin="12,12,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="350" />
    <Button Content="Start" Height="23" HorizontalAlignment="Left" Margin="12,226,0,0" Name="btnStart" VerticalAlignment="Top" Width="75" />
    <Button Content="Land" Height="23" HorizontalAlignment="Left" Margin="287,226,0,0" Name="btnLand" VerticalAlignment="Top" Width="75" />
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="110,226,0,0" Name="cmbChangeRoute" VerticalAlignment="Top" Width="156" />
</Grid>

编辑2: 我的问题已解决,这段代码运行良好:

BitmapImage image = new BitmapImage(
    new Uri("pack://application:,,,/Resources/" + company + ".png"));
image2.Source = image;

2
那前两行代码肯定是错的;Uri 不是图片。 - Emond
谢谢!但是它抱怨路径不对!它在寻找 C: 路径,但应该是 bin/debug 路径! - 3D-kreativ
2个回答

48
在WPF中,图像通常从StreamUri加载。 BitmapImage支持两者,甚至可以将Uri作为构造函数参数传递:
var uri = new Uri("http://...");
var bitmap = new BitmapImage(uri);

如果图像文件位于本地文件夹中,您必须使用 file:// Uri。您可以从如下路径创建此类 Uri:
var path = Path.Combine(Environment.CurrentDirectory, "Bilder", "sas.png");
var uri = new Uri(path);

如果图像文件是程序集资源,则 Uri 必须遵循 Pack Uri 方案:
var uri = new Uri("pack://application:,,,/Bilder/sas.png");

在这种情况下,sas.png 的 Visual Studio 构建操作必须是 Resource
一旦您创建了一个 BitmapImage 并且有一个像这样的 Image 控件在 XAML 中。
<Image Name="image1" />

你只需将BitmapImage指定给该Image控件的Source属性:

image1.Source = bitmap;

1
但是XAML中的代码呢?就像这样:<Image Name="Image1" /> - 3D-kreativ
不好意思,我错过了!既然我在bin/debug中有一个这样的文件夹,那么它应该可以工作吧?但是现在我正在尝试从资源中让它工作,并且希望得到一些帮助来让它工作。首先,我想我不需要在XAML代码中添加任何额外的内容,因为图像已经有一个名称:image1 ?? - 3D-kreativ
bin/Debug文件夹是不够的,它必须在你的VS项目中,就像我说的那样。而XAML <Image Name="image1" ... /> 会创建一个名为 image1 的成员变量,类型为 Image,它是一个WPF控件,而不是位图/图片。 - Clemens
我正在使用你的代码,但是我只收到一个关于Uri前缀未被识别的错误!? - 3D-kreativ
3
不需要使用BeginInit和EndInit。只需使用“BitmapImage(Uri)”构造函数即可。否则,该代码与我在这里回答的代码毫无区别,除了文件夹名为“Resources”,而不是“Bilder”。 - Clemens
显示剩余4条评论

7

确保你的 sas.png 在 Visual Studio 的 属性 中被标记为 Build Action: ContentCopy To Output Directory: Copy Always...

我认为 C# 源代码是这样的...

Image image = new Image();
image.Source = (new ImageSourceConverter()).ConvertFromString("pack://application:,,,/Bilder/sas.png") as ImageSource;

并且XAML应该被

<Image Height="200" HorizontalAlignment="Left" Margin="12,12,0,0" 
       Name="image1" Stretch="Fill" VerticalAlignment="Top" 
       Source="../Bilder/sas.png"
       Width="350" />  

编辑

我认为,在动态加载图片方面,XAML提供了最佳方式…

<Image Source="{Binding Converter={StaticResource MyImageSourceConverter}}"
       x:Name="MyImage"/>

其中image.DataContextstring路径。

MyImage.DataContext = "pack://application:,,,/Bilder/sas.png";

public class MyImageSourceConverter : IValueConverter
{
    public object Convert(object value_, Type targetType_, 
    object parameter_, System.Globalization.CultureInfo culture_)
    {
        return (new ImageSourceConverter()).ConvertFromString (value.ToString());
    }

    public object ConvertBack(object value, Type targetType, 
    object parameter, CultureInfo culture)
    {
          throw new NotImplementedException();
    }
}

现在您设置不同的数据上下文,Image 将自动在运行时加载。

嗯,但如果我想在运行时加载不同的图像呢?当我创建一个WPF窗口对象时,我想传递不同的图像,那么我猜XAML代码会有所不同?我已经将所有图像保存在Bin/Debug文件夹中,好吗? - 3D-kreativ
谢谢! 但他的方法难道不是太复杂了吗,仅仅为了使用一些图片吗? - 3D-kreativ
1
这就是我们在WPF中的做法... 如果您不想使用XAML,请使用我最初提供的C#代码... image.Source = (new ImageSourceConverter()).ConvertFromString("pack://application:,,,/Bilder/sas.png") as ImageSource; - WPF-it
谢谢你的帮助,但我正在使用另一段代码!请看我的第二个编辑。 - 3D-kreativ
你的意思是 value_.ToString() 吗? - tonydev314
这个答案大概是10年前发布的,但它刚好解决了我的问题!谢谢。 - Pablo Sarturi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接