Accès à une image en ressource

Signaler
Messages postés
78
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
14 août 2010
-
Messages postés
159
Date d'inscription
mardi 17 décembre 2002
Statut
Membre
Dernière intervention
23 novembre 2011
-
Bonjour,

J'ai un fichier de ressources qui contient plusieurs images.
Je n'ai pas de problème pour accéder aux différentes ressources qui le compose tant que j'utilise les classes spécifiques au projet.
Cependant pour des questions de réutisabilité, je voudrai pouvoir créer une classe générique me permettant d'accèder à une ressource sans avoir à préciser obligatoirement le nom de la classe utilisée par la form.

Exemple :
Dans mes projets skinnés, j'ai créé une classe nommé SkinEngine.cs dans laquelle j'ai la méthode suivante :


public static Bitmap GetResourceBitmap(string ResourceName, int width, int height)
{
    Bitmap bmp = new Bitmap(width, height);
    string sName = ResourceName.ToUpper();
    sName = sName.Replace("SKIN_", "");



    switch (sName)
    {
        case "BTN_CLOSE":
             bmp = BlackBox. Properties.Resources.BTN_Close; break;
        case "BTN_ICONIZE":
             bmp = BlackBox.Properties.Resources.BTN_Iconize; break;
        case "BTN_RESTORE":
             bmp = BlackBox. Properties.Resources.BTN_Restore; break;
        case "BTN_MAXIMIZE":
             bmp = BlackBox.Properties.Resources.BTN_Maximize; break;
        case "BTN_DOCKOUT":
             bmp = BlackBox. Properties.Resources.BTN_DockOut; break;
        case "BTN_DOCKIN":
             bmp = BlackBox.Properties.Resources.BTN_DockIn; break;
        case "BTN_ABOUT":
             bmp = BlackBox. Properties.Resources.BTN_About; break;
        default: bmp = BlackBox.Properties.Resources.BTN_Push; break;
    }
    return bmp;
}



Dans l'exemple ci-dessus partout ou figure BlackBox. je voudrai utiliser un nom générique au lieu du nom spécifique du projet.

Ou à la rigueur utiliser une MACRO du style
MACRO SkinForm = BlackBox
afin de pouvoir obtenir un code réutilisable sans avoir à chaque fois à modifier les lignes à la main.
(mais les macros ne sont pas disponibles en C#)

Avez-vous une suggestionr ?

Patrice Terrier
[url]www.zapsolution.com/url

12 réponses

Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
tu peux procéder de cette manière :

Stream stream = Assembly.GetAssembly(typeof(tonType)).GetManifestResourceStream("le.nom.de.ta.ressource.png")

Sébastien FERRAND (
blog)
Consultant Indépendant
[Microsoft MVP Visual C#]
Messages postés
5487
Date d'inscription
dimanche 4 août 2002
Statut
Modérateur
Dernière intervention
20 juin 2013
49
Un petit link sur codyx en supplément de la réponse de Seb'

-Blog-
Messages postés
78
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
14 août 2010

Sébastien,

Je débute en C# (et dans la POO), alors je ne sais pas à quoi doit correspondre "tonType"

Je suppose que je dois utiliser la directive


using
System.Reflection;

Puis convertir Stream en Bitmap ?

Patrice Terrier
www.zapsolution.com










 
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
pour convertir un stream en Bitmap...

Bitmap b = Bitmap.FromStream( maStream );

Sébastien FERRAND (
blog)
Consultant Indépendant
[Microsoft MVP Visual C#]
Messages postés
78
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
14 août 2010

Bidou - Merci pour le lien,
mais justement je ne veux pas avoir à préciser le NameSpace.
Je veux un code indépendant comme je pourrai le faire en mode procédural pour charger une ressource à partir d'un EXE ou d'une DLL Win32 en utilisant l'API LoadImage.



Sébastien -
dans l'exemple que vous donnez, 
je ne sais pas à quoi doit correspondre "tonType" ?

patrice
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
le tonType... c'est un type contenu dans l'assembly que tu veux charger...

si part exemple, tu veux l'assembly courant, il suffit de remplacer par this.GetType()...

Sébastien FERRAND (
blog)
Consultant Indépendant
[Microsoft MVP Visual C#]
Messages postés
78
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
14 août 2010

Ok, comme je ne peux pas utiliser this dans une méthode static, je vais me débrouiller autrement.



Même si mon problème n'est pas résolu, je vous dis néanmoins merci a tous les deux pour avoir pris le temps de me répondre.



Patrice Terrier
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
32
Salut, si il s'agit de réutiliser ton code à la compilation, tu peux faire un clique droit dans ton projet sur le fichier "Resources.resx" et changer sa propriété "Espace de noms de l'outil" ( rebuild si ça prend pas effet tout de suite ).

Sinon pour eviter les noms à rallonge générés par VS2005 tu peux créer ton propre fichier *.resources qui contiendra donc déja toutes tes images ( c'est plus simple avec Resourcer.NET ) et puis pour les récupérer :

ResourceManager rm = new ResourceManager( "MyRes", typeof( MainForm ).Assembly );
bmp = new Bitmap( ( Bitmap )rm.GetObject( "MyBitmap.bmp" ) );


Le problème c'est que ça marche très bien avec le compilo en ligne de commande ( csc.exe -t:winexe -resource:MyRes.resources main.cs ) mais j'ai pas trouvé comment faire avec Visual Studio, apparemment il créer les fichiers *.resources à partir des *.resx mais il ne les prend pas en charge directement. ( j'ai que la version Express d'installée c'est peut être pour ça aussi.. ).

Je sais pas si ça répond vraiment à ta question.. ^^
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
Le plus simple...

Tu crées un project "Class Library", dans lequel tu mets toutes tes images...
Tu crées une classe static et tu y colles ca :

public static class Resourcer {
   private static ResourceManager rm = new ResourceManager(typeof(Resourcer));

   public static Bitmap GetBitmap(string bitmap) {
      return rm.GetObject( typeof(Resourcer).Assembly.FullName + "." + bitmap) as Bitmap;
   }
}

Comme ca, il te suffit d'appeler la méthode GetBitmap avec le nom de ton image pour la récupérer.

Exemple :
Pour récupérer l'image : toto.bmp
Bitmap toto = Resourcer.GetBitmap("toto.bmp");

Pour récupérer l'image : titi.png du dossier /Images/Droles
Bitmap titi = Resourcer.GetBitmap("Images.Droles.titi.png");

Voila :)

Avec tout ca, ca me fait penser que je pourrais faire une source la dessus :)

Sébastien FERRAND (
blog)
Consultant Indépendant
[Microsoft MVP Visual C#]
Messages postés
78
Date d'inscription
mardi 31 décembre 2002
Statut
Membre
Dernière intervention
14 août 2010

Merci pour ces informations complémentaires.

Comme je l'ai indiqué dans mon mail précédent je me suis débrouillé autrement.

Voici le code que j'utilise :



Dans ma classe SK (Skin Engine)

j'ai ajouté une propriété UseNamespace,
afin de récupérer le NameSpace de l'application hôte
SK.UseNameSpace = this.GetType().Namespace;



puis j'ai ajouté la méthode Bitmap GetBitmapFromResource (string MonImage)
qui me permet d'avoir un code portable.



namespace SkinEngine
{
    class SK
    {
        private static string usenamespace = null;
        public static string UseNameSpace
        {
            get { return usenamespace; }
            set { usenamespace = value; }
        }




        public static Bitmap GetBitmapFromResource(string imgName)
        {
            string path = string.Format("{0}.Properties.Resources", UseNameSpace);
            System.Resources.ResourceManager resourceManager = new System.Resources.ResourceManager(path, typeof( SK ).Assembly);
            object obj = resourceManager.GetObject(imgName);
            return ((System.Drawing.Bitmap)(obj));
        }
etc.



Remarque : La gestion des ressources avec DotNET, c'est galère, comparé à Win32.



En ce qui me concerne le sujet est clos.
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
32
Petite précision sur ce que j'ai dit.. Entre temps j'ai refait des tests, et donc visual studio ( même la version Express ) prend bien en charge les fichiers *.resources. la seul différence avec le compilateur en ligne de commande c'est qu'il rajoute le namespace au nom de la ressource.
Messages postés
159
Date d'inscription
mardi 17 décembre 2002
Statut
Membre
Dernière intervention
23 novembre 2011

Et comment récupérer une resource (genre image) dans un projet WPF qui ne figure pas dans le MyAssembly.Properties.Resources.MyResource. La resource (ou fichier) a dans ses options l'action de génération à "Contenu" ou "Resource" donc dans l'éditeur WPF les resources sont accessible par "pack://application:,,,/Dossier/nomimage.extension" example
.
Mais pour crée un control Image (et pas un PictureBox en WinForm) pour lui donner une image ont doit lui assigne le chemin du fichier via Source et en code (C#) je ne sais pas comment lui assigner cette valeur si je copie pas le fichier dans le dossier de sortie. Quelqu'un aurait une idée ?