web-dev-qa-db-fra.com

Ressources d'images WPF

Je viens d’un contexte essentiellement web et un peu Windows Forms. Pour un nouveau projet, nous utiliserons WPF. L'application WPF aura besoin de 10 à 20 petites icônes et images à des fins d'illustration. Je songe à les stocker dans l’Assemblée en tant que ressources intégrées. Est-ce la bonne façon de faire?

Comment spécifier dans XAML qu'un contrôle Image doit charger l'image à partir d'une ressource incorporée?

385
driis

Si vous souhaitez utiliser l'image à plusieurs endroits, il est intéressant de ne charger les données d'image qu'une seule fois en mémoire, puis de les partager entre tous les éléments Image.

Pour ce faire, créez un BitmapSource en tant que ressource quelque part:

<BitmapImage x:Key="MyImageSource" UriSource="../Media/Image.png" />

Ensuite, dans votre code, utilisez quelque chose comme:

<Image Source="{StaticResource MyImageSource}" />

Dans mon cas, j’ai trouvé que je devais définir le fichier Image.png pour avoir une action de compilation de Resource plutôt que simplement Content. Cela entraîne l'image dans votre Assemblée compilée.

458
Drew Noakes

La meilleure pratique pour utiliser des images, des vidéos, etc. est la suivante:

  • Changez vos fichiers "Action de construction" en "Contenu". Assurez-vous de cocher dans le répertoire de construction .
    • Trouvé dans le menu "Clic droit" de la fenêtre de l'Explorateur de solutions.
  • Source de l'image au format suivant:
    • "/ " YourAssemblyName "; composant /" YourPath "/ " YourImage.png " "

Exemple

<Image Source="/WPFApplication;component/Images/Start.png" />

Avantages:

  • Les fichiers ne sont pas intégrés à l’Assemblée.
    • Le Gestionnaire de ressources soulèvera des problèmes de dépassement de mémoire avec trop de ressources (au moment de la construction).
  • Peut être appelé entre les assemblées.
165
Nuno Rodrigues

Certaines personnes demandent de faire cela dans le code sans obtenir de réponse.

Après avoir passé de nombreuses heures à chercher, j'ai trouvé une méthode très simple, je n'ai trouvé aucun exemple et je partage donc le mien ici, qui fonctionne avec des images. (le mien était un .gif)

Sommaire:

Il retourne un BitmapFrame que les "destinations" d'ImageSource semblent aimer.

Utilisation:

doGetImageSourceFromResource ("[YourAssemblyNameHere]", "[YourResourceNameHere]");

Méthode:

static internal ImageSource doGetImageSourceFromResource(string psAssemblyName, string psResourceName)
{
    Uri oUri = new Uri("pack://application:,,,/" +psAssemblyName +";component/" +psResourceName, UriKind.RelativeOrAbsolute);
    return BitmapFrame.Create(oUri);
}

Apprentissages:

D'après mes expériences, la chaîne de pack n'est pas le problème, vérifiez vos flux et surtout si vous le lisez pour la première fois, le pointeur se trouve à la fin du fichier et vous devez le réinitialiser à zéro avant de relire.

J'espère que cela vous épargnera les nombreuses heures que j'aurais souhaité pour cette pièce!

45
Craig

Dans le code pour charger une ressource dans l'assembly en cours d'exécution où mon image Freq.png se trouvait dans le dossier Icons et définie comme Resource:

this.Icon = new BitmapImage(new Uri(@"pack://application:,,,/" 
    + Assembly.GetExecutingAssembly().GetName().Name 
    + ";component/" 
    + "Icons/Freq.png", UriKind.Absolute)); 

J'ai aussi créé une fonction:

/// <summary>
/// Load a resource WPF-BitmapImage (png, bmp, ...) from embedded resource defined as 'Resource' not as 'Embedded resource'.
/// </summary>
/// <param name="pathInApplication">Path without starting slash</param>
/// <param name="Assembly">Usually 'Assembly.GetExecutingAssembly()'. If not mentionned, I will use the calling Assembly</param>
/// <returns></returns>
public static BitmapImage LoadBitmapFromResource(string pathInApplication, Assembly assembly = null)
{
    if (Assembly == null)
    {
        Assembly = Assembly.GetCallingAssembly();
    }

    if (pathInApplication[0] == '/')
    {
        pathInApplication = pathInApplication.Substring(1);
    }
    return new BitmapImage(new Uri(@"pack://application:,,,/" + Assembly.GetName().Name + ";component/" + pathInApplication, UriKind.Absolute)); 
}

Utilisation (en supposant que vous placiez la fonction dans une classe ResourceHelper):

this.Icon = ResourceHelper.LoadBitmapFromResource("Icons/Freq.png");

Remarque : voir DN du pack MSDN dans WPF :
pack://application:,,,/ReferencedAssembly;component/Subfolder/ResourceFile.xaml

39
Eric Ouellet

Oui, c'est la bonne façon.

Vous pouvez utiliser l'image dans le fichier de ressources en utilisant simplement le chemin:

<Image Source="..\Media\Image.png" />

Vous devez définir l'action de construction du fichier image sur "Ressource".

38
ema

Description complète de l'utilisation des ressources: ressources, contenu et fichiers de données d'application WPF

Et comment les référencer, lisez "Pack URIs in WPF".

En bref, il existe même des moyens de référencer des ressources à partir d'assemblys référencés/référencés.

13
techfan
  1. Visual Studio 2010 Professional SP1.
  2. Profil client .NET Framework 4.
  3. Image PNG ajoutée en tant que ressource sur les propriétés du projet.
  4. Nouveau fichier dans le dossier Ressources créé automatiquement.
  5. Construire un jeu d’action sur la ressource.

Cela a fonctionné pour moi:

<BitmapImage x:Key="MyImageSource" UriSource="Resources/Image.png" />
4
JoanComasFdz

Oui, c'est la bonne façon. Vous pouvez utiliser des images dans le fichier de ressources en utilisant un chemin:

<StackPanel Orientation="Horizontal">
    <CheckBox  Content="{Binding Nname}" IsChecked="{Binding IsChecked}"/>
    <Image Source="E:\SWorking\SharePointSecurityApps\SharePointSecurityApps\SharePointSecurityApps.WPF\Images\sitepermission.png"/>
    <TextBlock Text="{Binding Path=Title}"></TextBlock>
</StackPanel>
3
Sanjay Ranavaya

Si vous utilisez Mélange , pour que ce soit très facile et ne rencontrez aucun problème pour obtenir le chemin correct pour l'attribut Source , glissez et déposez l’image du panneau Projet dans le concepteur.

3
user42467