Configurar o código da imagem WPF em código

Estou a tentar definir a fonte de uma imagem WPF em código. A imagem está embutida como um recurso no projeto. Ao olhar para exemplos, eu encontrei o código abaixo. Por alguma razão não funciona - a imagem não aparece.

ao depurar consigo ver que o fluxo contém os dados da imagem. Então, o que se passa?

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;

o ícone é definido como algo assim: <Image x:Name="_icon" Width="16" Height="16" />

Author: Arcturus, 2008-12-08

18 answers

Depois de ter o mesmo problema que tu e de fazer alguma leitura, descobri a solução - Pack URIs .

Fiz o seguinte em código:

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;

Ou mais curto, utilizando outro construtor de Bitmapimagens:

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

O URI está dividido em partes:

  • Autoridade: application:///
  • Localização: o nome de um ficheiro de recursos que é compilado num conjunto referenciado. O canal horário deve estar em conformidade com o seguinte formato:: AssemblyShortName[;Version][;PublicKey];component/Path

    • AssemblyShortName: o nome abreviado para a Assembleia referenciada.
    • ; Versão [opcional]: a versão da montagem referenciada que contém o ficheiro de recursos. Isto é usado quando dois ou mais conjuntos referenciados com o mesmo nome curto são carregados.
    • ; PublicKey [opcional]: a chave pública que foi usada para assinar a montagem referenciada. Isto é usado quando dois ou mais conjuntos referenciados com o mesmo nome curto são carregados.
    • ; componente: especifica que a Assembleia a que se refere é referenciada a partir da assembleia local.
    • / localização: o nome do ficheiro de recursos, incluindo a sua localização, em relação à raiz da pasta de Projecto do conjunto referenciado.

Os três cortes após application: têm de ser substituídos por vírgulas:

Nota: O elemento de Autoridade de uma embalagem é um URI incorporado que aponta para um embalagem e deve estar em conformidade com a RFC 2396. Além disso, o carácter " / " deve ser substituído pelo carácter",", e caracteres reservados como"%" e "?"deve ter escapado. Ver o OPC para mais detalhes.

E, claro, certifique-se que configura a acção de compilação na sua imagem para Resource.

 427
Author: Jared Harley, 2017-11-07 06:49:17
var uriSource = new Uri(@"/WpfApplication1;component/Images/Untitled.png", UriKind.Relative);
foo.Source = new BitmapImage(uriSource);

Isto irá carregar uma imagem Chamada " Sem Título.png "em uma pasta chamada" Imagens "com sua" ação de construção "definida para" recurso "em uma montagem chamada"WpfApplication1".

 177
Author: Simon, 2011-06-09 11:36:50

Este é um pouco menos código e pode ser feito em uma única linha.

string packUri = "pack://application:,,,/AssemblyName;component/Images/icon.png";
_image.Source = new ImageSourceConverter().ConvertFromString(packUri) as ImageSource;
 76
Author: Alex B, 2010-01-06 17:47:13

Muito fácil:

Para definir dinamicamente a imagem de um item de menu, faça apenas o seguinte:

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

...considerando que " icon.o ico " pode ser localizado em todos os lugares (atualmente está localizado no diretório 'recursos') e deve ser ligado como recurso...

 47
Author: A Bothe, 2015-12-15 10:25:34

A maneira mais simples:

var uriSource = new Uri("image path here");
image1.Source = new BitmapImage(uriSource);
 17
Author: Hasan, 2018-05-19 12:43:19

Também pode reduzir isto para uma linha. Este é o código que usei para definir o ícone da minha janela principal. Assume o ... o ficheiro ico está marcado como Conteúdo e está a ser copiado para a pasta de saída.

 this.Icon = new BitmapImage(new Uri("Icon.ico", UriKind.Relative));
 16
Author: Payson Welch, 2011-02-13 17:09:08

Já tentaste:

Assembly asm = Assembly.GetExecutingAssembly();
Stream iconStream = asm.GetManifestResourceStream("SomeImage.png");
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.StreamSource = iconStream;
bitmap.EndInit();
_icon.Source = bitmap;
 15
Author: Andrew Myhre, 2009-02-09 22:37:41
Este é o meu caminho.
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);
    }
}

Utilização:

new BitmapImage(ResourceAccessor.Get("Images/1.png"))
 13
Author: IlPADlI, 2018-07-14 06:22:52

Aqui está um exemplo que define dinamicamente o caminho da imagem (Imagem localizada algures no disco em vez de ser construída como recurso):

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

Reflexões sobre Ícones...

Primeiro pensei que você pensaria que a propriedade dos ícones só pode conter uma imagem. Mas pode conter qualquer coisa! Eu descobri isso por acidente quando programaticamente tentei definir a propriedade Image diretamente em uma corda com o caminho para uma imagem. O resultado foi que não mostrou a imagem, mas o texto real do caminho!

Isto leva a uma alternativa para não ter que fazer uma imagem para o ícone, mas usar o texto com um tipo de letra símbolo em vez de mostrar um simples "ícone". O exemplo a seguir usa o tipo de letra Wingdings que contém um símbolo "floppydisk". Este símbolo é realmente o personagem <, que tem um significado especial no XAML, por isso temos de usar a versão codificada &lt; em vez disso. Isto funciona como um sonho! O seguinte mostra um símbolo floppydisk como um ícone no menu item:

<MenuItem Name="mnuFileSave" Header="Save" Command="ApplicationCommands.Save">
  <MenuItem.Icon>
    <Label VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Wingdings">&lt;</Label>
  </MenuItem.Icon>
</MenuItem>
 8
Author: awe, 2018-05-19 12:25:00

Se a sua imagem está armazenada num recurso, só pode fazê-lo com uma linha de código:

MyImage.Source = MyImage.FindResource("MyImageKeyDictionary") as ImageSource;
 8
Author: Hollyroody, 2018-05-19 12:45:25
Há também uma maneira mais simples. Se a imagem for carregada como um recurso no XAML, e o código em questão for o código atrás para esse conteúdo do XAML:
Uri iconUri = new Uri("pack://application:,,,/ImageNAme.ico", UriKind.RelativeOrAbsolute);
NotifyIcon.Icon = BitmapFrame.Create(iconUri);
 6
Author: Bharat Thanki, 2018-05-19 12:32:13

Coloque a moldura num Visualizador:

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

brush.Visual = frame;

brush.AlignmentX = AlignmentX.Center;
brush.AlignmentY = AlignmentY.Center;
brush.Stretch = Stretch.Uniform;
Põe o visualizador em 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;
Agora põe a GeometryDrawing numa imagem de desenho.
new DrawingImage(drawing);
Coloque isto na sua fonte da imagem, e voilà! Mas podias fazê-lo mais facilmente.
<Image>
    <Image.Source>
        <BitmapImage UriSource="/yourassembly;component/YourImage.PNG"></BitmapImage>
    </Image.Source>
</Image>

E em código:

BitmapImage image = new BitmapImage { UriSource="/yourassembly;component/YourImage.PNG" };
 5
Author: Arcturus, 2018-05-19 12:23:43
Há também uma maneira mais simples. Se a imagem é carregada como um recurso no XAML, e o código em questão é o codebehind para esse XAML:

Aqui está o dicionário de recursos para um ficheiro XAML - a única linha que lhe interessa é a ImageBrush com a chave "PosterBrush" - o resto do código é apenas para mostrar o contexto

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

        </ResourceDictionary>
    </UserControl.Resources>
Agora, no código atrás, podes fazer isto.
ImageBrush posterBrush = (ImageBrush)Resources["PosterBrush"];
 3
Author: Mark Mullin, 2018-05-19 12:27:06

Como carregar uma imagem incorporada em ícones de recursos e imagens (versão corrigida do Arcturus):

Suponha que quer adicionar um botão com uma imagem. O que deves fazer?

  1. Adicione aos ícones de pastas do projecto e coloque o ClickMe da imagem.png aqui
  2. em Propriedades de ClickMe.png', configure 'BuildAction' para 'Resource'
  3. Suponha que o seu nome compilado é "Companhia".Montagem.dll'.
  4. Agora é hora de carregar a nossa imagem em 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>
    
Feito.
 2
Author: Siarhei Kuchuk, 2018-05-19 12:28:59

Sou novo na WPF, mas não na NET.

Passei cinco horas a tentar adicionar um ficheiro PNG a um" projecto de biblioteca de controlo personalizado da WPF " no.NET 3.5 (Visual Studio 2010) e a configurá-lo como um fundo de um controlo herdado da imagem. Nada relacionado com URIs funcionou. Não consigo imaginar por que não há nenhum método para obter um URI de um arquivo de recursos, através do IntelliSense, talvez como: [[4]}
Properties.Resources.ResourceManager.GetURI("my_image");
Tentei muitos URIs e joguei com o Gestor de recursos, e a Assembleia Os métodos GetManifest, mas todos havia exceções ou valores nulos. Aqui ponho o código que funcionou comigo.
// 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;
 2
Author: JoanComasFdz, 2018-05-19 12:31:21

Se já tem um fluxo e conhece o formato, pode usar algo assim:

static ImageSource PngStreamToImageSource (Stream pngStream) {
    var decoder = new PngBitmapDecoder(pngStream,
        BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
    return decoder.Frames[0];
}
 1
Author: , 2010-04-11 08:14:43
Só falhaste um pouco.

Para obter um recurso incorporado de qualquer conjunto, você tem que mencionar o nome do conjunto com o seu nome de arquivo como eu mencionei aqui:

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;
 1
Author: maulik kansara, 2018-05-19 12:44:26

Aqui está se quiser localizá-lo ao lado do seu executável (relativo do executável)

img.Source = new BitmapImage(new Uri(AppDomain.CurrentDomain.BaseDirectory + @"\Images\image.jpg", UriKind.Absolute));
 0
Author: Donovan Phoenix, 2020-10-11 19:36:03