在代码中设置WPF图像源

Tor*_*ørn 316 .net c# wpf image

我正在尝试在代码中设置WPF图像的源代码.图像作为资源嵌入到项目中.通过查看示例,我提出了以下代码.由于某种原因,它不起作用 - 图像不显示.

通过调试,我可以看到流包含图像数据.那有什么不对?

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
PngBitmapDecoder iconDecoder = new PngBitmapDecoder(iconStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
ImageSource iconSource = iconDecoder.Frames[0];
_icon.Source = iconSource;
Run Code Online (Sandbox Code Playgroud)

图标的定义如下: <Image x:Name="_icon" Width="16" Height="16" />

Jar*_*ley 404

在遇到与您相同的问题并进行一些阅读后,我发现了解决方案 - 包URI.

我在代码中做了以下事情:

Image finalImage = new Image();
finalImage.Width = 80;
...
BitmapImage logo = new BitmapImage();
logo.BeginInit();
logo.UriSource = new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png");
logo.EndInit();
...
finalImage.Source = logo;
Run Code Online (Sandbox Code Playgroud)

或者更短,使用另一个BitmapImage构造函数:

finalImage.Source = new BitmapImage(
    new Uri("pack://application:,,,/AssemblyName;component/Resources/logo.png"));
Run Code Online (Sandbox Code Playgroud)

URI分为几部分:

  • 权威: application:///
  • 路径:编译为引用的程序集的资源文件的名称.路径必须符合以下格式:AssemblyShortName[;Version][;PublicKey];component/Path

    • AssemblyShortName:引用的程序集的简称.
    • ; Version [可选]:包含资源文件的引用程序集的版本.当加载两个或多个具有相同短名称的引用程序集时,将使用此方法.
    • ; PublicKey [可选]:用于对引用的程序集进行签名的公钥.当加载两个或多个具有相同短名称的引用程序集时,将使用此方法.
    • ; component:指定从本地程序集引用所引用的程序集.
    • / Path:相对于引用程序集的项目文件夹的根目录的资源文件的名称,包括其路径.

之后的三个斜线application:必须用逗号替换:

注意:包URI的权限组件是指向包的嵌入式URI,必须符合RFC 2396.此外,"/"字符必须替换为","字符和保留字符,例如"%"和"?" 必须逃脱.有关详细信息,请参阅OPC.

当然,请确保将图像上的构建操作设置为Resource.

  • 好的,但是没有XAML解析器用来将简单路径字符串转换为ImageSource的方法或类吗?我们不能只使用它吗? (9认同)

Sim*_*mon 170

var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);
Run Code Online (Sandbox Code Playgroud)

这将在名为"Images"的文件夹中加载一个名为"Untitled.png"的图像,其"Build Action"在名为"WpfApplication1"的程序集中设置为"Resource".

  • 感谢那.将我作为一个菜鸟绊到wpf的一个问题,必须将图像标记为此工作的资源. (16认同)
  • `var uriSource = new Uri("Images/Untitled.png",UriKind.Relative);`就足够了 (8认同)
  • 这个解决方案给了我一个例外,所以我尝试了Jared Harley的解决方案并且它有效... (4认同)
  • 最重要的是"UriKind.RelativeOrAbsolute" - 其他例子总是抛出异常 (2认同)

Ale*_*x B 74

这是一个较少的代码,可以在一行中完成.

string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是利用.NET自己实现的最佳答案 (8认同)

小智 41

很容易:

要动态设置菜单项的图像,只需执行以下操作:

MyMenuItem.ImageSource = 
    new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));
Run Code Online (Sandbox Code Playgroud)

...而"icon.ico"可以位于任何地方(目前它位于"资源"目录中),并且必须作为资源链接...

  • 当我分配imagesource时,它只是显示空白:( (3认同)
  • 更短=更好.我不得不把它设置为@"/ folder/image.png"但是它工作得很好.谢谢! (2认同)

Pay*_*lch 16

您也可以将其减少到一行.这是我用来为我的主窗口设置Icon的代码.它假定.ico文件被标记为内容并被复制到输出目录.

 this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
Run Code Online (Sandbox Code Playgroud)


Has*_*san 15

最简单的方法:

var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
Run Code Online (Sandbox Code Playgroud)


And*_*hre 14

你有没有尝试过:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
Run Code Online (Sandbox Code Playgroud)


小智 11

这是我的方式:

internal static class ResourceAccessor
{
    public static Uri Get(string resourcePath)
    {
        var uri = string.Format(
            "pack://application:,,,/{0};component/{1}"
            , Assembly.GetExecutingAssembly().GetName().Name
            , resourcePath
        );

        return new Uri(uri);
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

new BitmapImage(ResourceAccessor.Get("Images/1.png"))
Run Code Online (Sandbox Code Playgroud)


awe*_*awe 8

下面是一个动态设置图像路径的示例(图像位于光盘上的某个位置而不是构建为资源):

if (File.Exists(imagePath))
{
    // Create image element to set as icon on the menu element
    Image icon = new Image();
    BitmapImage bmImage = new BitmapImage();
    bmImage.BeginInit();
    bmImage.UriSource = new Uri(imagePath, UriKind.Absolute);
    bmImage.EndInit();
    icon.Source = bmImage;
    icon.MaxWidth = 25;
    item.Icon = icon;
}
Run Code Online (Sandbox Code Playgroud)

关于图标的思考......

首先想到的是,你会认为Icon属性只能包含一个图像.但它实际上可以包含任何东西!当我以编程方式尝试将Image属性直接设置为带有图像路径的字符串时,我意外地发现了这一点.结果是它没有显示图像,而是显示路径的实际文本!

这导致了不必为图标制作图像的替代方案,而是使用带有符号字体的文本来显示简单的"图标".以下示例使用Wingdings字体,其中包含"floppydisk"符号.这个符号实际上是字符<,它在XAML中具有特殊含义,因此我们必须使用编码版本&lt;.这就像一场梦!以下显示了一个floppydisk符号作为菜单项上的图标:

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>
</MenuItem>
Run Code Online (Sandbox Code Playgroud)


小智 6

如果您的图像存储在ResourceDictionary中,则只需一行代码即可完成:

MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;
Run Code Online (Sandbox Code Playgroud)


Arc*_*rus 5

将框架放在 VisualBrush 中:

VisualBrush brush = new VisualBrush { TileMode = TileMode.None };

brush.Visual = frame;

brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;
Run Code Online (Sandbox Code Playgroud)

将 VisualBrush 放入 GeometryDrawing

GeometryDrawing drawing = new GeometryDrawing();

drawing.Brush = brush;

// Brush this in 1, 1 ratio
RectangleGeometry rect = new RectangleGeometry { Rect = new Rect(0, 0, 1, 1) };
drawing.Geometry = rect;
Run Code Online (Sandbox Code Playgroud)

现在将 GeometryDrawing 放在 DrawingImage 中:

new DrawingImage(drawing);
Run Code Online (Sandbox Code Playgroud)

把它放在你的图像来源上,瞧!

不过,您可以更轻松地做到这一点:

<Image>
    <Image.Source>
        <BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
    </Image.Source>
</Image>
Run Code Online (Sandbox Code Playgroud)

在代码中:

BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };
Run Code Online (Sandbox Code Playgroud)


小智 5

还有一种更简单的方法.如果图像作为资源加载到XAML中,并且有问题的代码是该XAML内容的代码隐藏:

Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute);
NotifyIcon.Icon = BitmapFrame.Create(iconUri);
Run Code Online (Sandbox Code Playgroud)