我试图在代码中设置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;

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


将框架放在VisualBrush中:

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

brush.Visual = frame;

brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;

把VisualBrush放在几何绘图中

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;

现在将几何绘图放在DrawingImage中:

new DrawingImage(drawing);

把这个放在你的图片源上,然后是voilà!

你可以做得更简单:

<Image>
    <Image.Source>
        <BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
    </Image.Source>
</Image>

在代码中:

BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };

你有没有试过:

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

下面是一个动态设置映像路径的例子(映像位于磁盘上的某个位置,而不是作为资源构建):

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;
}

关于图标的思考……

首先,您可能认为Icon属性只能包含图像。但它实际上可以包含任何东西!当我试图通过编程方式将Image属性直接设置为包含图像路径的字符串时,我偶然发现了这一点。结果是它没有显示图像,而是显示路径的实际文本!

这导致了一种不必为图标制作图像的替代方案,而是使用带有符号字体的文本来显示简单的“图标”。下面的例子使用了包含“软盘”符号的Wingdings字体。这个符号实际上是字符<,它在XAML中有特殊的含义,所以我们必须使用编码版本&lt;代替。这就像做梦一样!下面将软盘符号显示为菜单项上的图标:

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>
</MenuItem>

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

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


在遇到与您相同的问题并进行了一些阅读之后,我发现了解决方案—打包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;

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

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

URI被分成几个部分:

Authority: application:/// Path: The name of a resource file that is compiled into a referenced assembly. The path must conform to the following format: AssemblyShortName[;Version][;PublicKey];component/Path AssemblyShortName: the short name for the referenced assembly. ;Version [optional]: the version of the referenced assembly that contains the resource file. This is used when two or more referenced assemblies with the same short name are loaded. ;PublicKey [optional]: the public key that was used to sign the referenced assembly. This is used when two or more referenced assemblies with the same short name are loaded. ;component: specifies that the assembly being referred to is referenced from the local assembly. /Path: the name of the resource file, including its path, relative to the root of the referenced assembly's project folder.

application:后面的三个斜杠必须用逗号代替:

注意:包URI的授权组件 是一个嵌入式URI,指向 包装,必须符合RFC 2396。 此外,“/”字符必须 替换为“,”字符, 以及保留字符,如“%” "?"必须转义。查看OPC 获取详细信息。

当然,还要确保将映像上的构建操作设置为Resource。


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

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

还有一种更简单的方法。如果图像在XAML中作为资源加载,并且所讨论的代码是该XAML的幕后代码:

下面是一个XAML文件的资源字典——你唯一关心的一行是ImageBrush,键为“PosterBrush”——其余的代码只是用来显示上下文

<UserControl.Resources>
        <ResourceDictionary>
            <ImageBrush x:Key="PosterBrush" ImageSource="..\Resources\Images\EmptyPoster.jpg" Stretch="UniformToFill"/>

        </ResourceDictionary>
    </UserControl.Resources>

在后面的代码中,你可以这样做

ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"];

如何从嵌入的资源图标和图像(校正版本的Arcturus)加载图像:

假设您想添加一个带有图像的按钮。你该怎么办?

Add to project folder icons and put image ClickMe.png here In properties of 'ClickMe.png', set 'BuildAction' to 'Resource' Suppose your compiled assembly name is 'Company.ProductAssembly.dll'. Now it's time to load our image in XAML <Button Width="200" Height="70"> <Button.Content> <StackPanel> <Image Width="20" Height="20"> <Image.Source> <BitmapImage UriSource="/Company.ProductAssembly;component/Icons/ClickMe.png"></BitmapImage> </Image.Source> </Image> <TextBlock HorizontalAlignment="Center">Click me!</TextBlock> </StackPanel> </Button.Content> </Button>

完成了。


如果你已经有了一个流,并且知道它的格式,你可以使用这样的东西:

static ImageSource PngStreamToImageSource (Stream pngStream) {
    var decoder = new PngBitmapDecoder(pngStream,
        BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    return decoder.Frames[0];
}

我是WPF的新手,但不熟悉。net。

我花了五个小时尝试在。net 3.5 (Visual Studio 2010)中添加一个PNG文件到“WPF自定义控件库项目”,并将其设置为图像继承控件的背景。

与uri相关的任何东西都不起作用。我无法想象为什么没有方法从资源文件中获取URI,通过智能感知,可能是:

Properties.Resources.ResourceManager.GetURI("my_image");

我已经尝试了很多uri和ResourceManager,以及Assembly的GetManifest方法,但都有异常或NULL值。

在这里我罐的代码,为我工作:

// Convert the image in resources to a Stream
Stream ms = new MemoryStream()
Properties.Resources.MyImage.Save(ms, ImageFormat.Png);

// Create a BitmapImage with the stream.
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = ms;
bitmap.EndInit();

// Set as source
Source = bitmap;

还有一种更简单的方法。如果图像在XAML中作为资源加载,并且所讨论的代码是该XAML内容的幕后代码:

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

很简单:

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

MyMenuItem.ImageSource = 
    new BitmapImage(new Uri("Resource/icon.ico",UriKind.Relative));

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


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

 this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));

最简单的方法:

var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);

你只是漏了一点。

要从任何程序集获取嵌入式资源,你必须像我在这里提到的那样,用你的文件名提到程序集名称:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream(asm.GetName().Name + "." + "Desert.jpg");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
image1.Source = bitmap;

这是我的方式:

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);
    }
}

用法:

new BitmapImage(ResourceAccessor.Get("Images/1.png"))

如果你的图像存储在ResourceDictionary中,你只需要一行代码就可以做到:

MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;

如果你想把它定位在可执行文件旁边(相对于可执行文件)

img.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + @"\Images\image.jpg", UriKind.Absolute));

Force选择UriKind将是正确的:

Image.Source = new BitmapImage(new Uri("Resources/processed.png", UriKind.Relative));

UriKind可选:

UriKind.Relative // relative path
UriKind.Absolute // exactly path