IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

[VB.NET] Copier une partie d'une image BITMAP dans une autre


Sujet :

VB.NET

  1. #21
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Citation Envoyé par Aspic Voir le message
    EDIT: Dans ton code ctxnop, j'ai une erreur bizarre :

    Y'a une assembly a rajouter ou pas ?
    Non pas d'assembly a rajouter, ce type est écris dans le fichier du même nom GridPictureBox.cs.
    Je présume que n'ayant pas la même version de studio que moi tu as recréé un projet pour y ajouter les fichiers manuellement et que tu as omis celui-ci par inadvertance ?

    Edit :
    Ou sinon, cette erreur peut également arriver quand tu ouvre TilePainterForm en mode design. La raison est simple, ce formulaire contient deux instances du GridPictureBox il a donc besoin de l'assembly dans lequel ils se trouvent, or cet assembly n'existe qu'après avoir compiler ton projet.
    Donc tu fais une première fois "générer le projet" et après seulement tu pourra ouvrir le formulaire en mode design.

  2. #22
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonsoir

    [mode famille] Dès que j'ai cinq minutes je te poste ça, au plus tard lundi car cela me sera plus facile (les PC de la maison sont d'une lenteur ! Et leur mono écran en 19" sont d'un ch***) [/mode famille]

  3. #23
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    C'est bon j'ai reussi à régler le problème

    J'ai testé ta grille c'est génial

    J'aimerais l'améliorer mais je me demandais avec ton système si c'était possible de créer une bordure plus grosse et d'une autre couleurs sur le tile sélectionné dans la grille des tilles ? Ca serait mieux pour l'utilisateur que d'utiliser une pictureBox qui montre le tile sélectionné...

    Edit :

    J'ai aussi essayé de coder une fonction zoom (x2) mais c'est bizarre, il ne redessine pas la grille (qui passe bien en 32 par 32px, cf pièce jointe) sur la totalité de l'image resizée. Et avec le débogeur, j'ai vu que les propriétés Height et Width de Image ne sont pas modifiées et elles sont en readOnly...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    private void b_zoom_Click(object sender, EventArgs e)
            {
                gpbDestination.SizeMode = PictureBoxSizeMode.Zoom;
                gpbDestination.Size = new Size(gpbDestination.Image.Width * 2, gpbDestination.Image.Height * 2);
                gpbDestination.GridHeight *= 2;
                gpbDestination.GridWidth *= 2;
                gpbDestination.Refresh();
            }
    Après y'aura l'histoire de stretch les tiles mais c'est autre chose...

    Une idée ? (whaou première fois de ma vie que je code en C# )
    Images attachées Images attachées  

  4. #24
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    La GridPictureBox j'ai codé ca en 3 minutes, j'ai rien prévu pour zoomer et vu qu'elle se dessine en fonction de la dimension de l'image, sachant qu'un zoom ne change pas la dimension de l'image mais bien celle du rendu.

    Il faudrait que tu modifies la fonction de dessin (OnPaint) présente dans la GridPictureBox pour y inclure une gestion du zoom et donc introduire le facteur de zoom dans le calcul de la position des lignes.

    Sinon, de base, j'avais déjà mis des propriétés pour changer l'épaisseur et même la couleur du trait de la grille.

    Donc le truc serai d'ajouter 3 propriétés supplémentaires
    - HighlightSelected : un bool indiquant si la grille met en surbrillance l'élément de la grille sélectionné
    - HighlightSize : un int définissant l'épaisseur de la bordure pour l'élément sélectionné
    - HighlightColor : une couleur utilisée pour colorier cette bordure.

    Il te faudra aussi une variable locale de type Rectangle pour stocker la position et les dimension de l'élément sélectionné.

    Ensuite, tu surcharges la méthode OnClick en t'inspirant de l'évènement Click posé sur le gpbTiles, la méthode doit calculer le rectangle sélectionné lors du click.

    Enfin, dans la méthode OnPaint, à la fin, tu ajoute le dessin du rectangle en fonction des trois propriétés évoquées plus haut.

    Pour finir, j'ai fais ca en C# parce que je préfère la syntaxe à celle du VB et comme c'était un truc en speed j'avais la flemme de taper ca en VB, surtout que sur un petit truc comme ca les différences entre les deux sont extrêmement minimes. Ceci dit, tu peux passer le projet dans un convertisseur C#<->VB sans trop de problème je pense.

    Dans ma boite on codait autant en VB qu'en C# mais dernièrement on a décider d'arrêter le plus possible le VB, ca rend l'IDE trop instable et provoque des problèmes dans les procédures de compilations. Au point qu'on a été obligé de coder des utilitaires qui parsent les fichiers de projets et compilent la solution par étape en ligne de commande...
    Du coup je commence a perdre l'habitude de coder en VB.

  5. #25
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Merci pour ces infos, j'ai tenté quelque chose que semble marcher mais le problème c'est lorsque je change de tile sélectionné, il faudrait effacer l'ancien tile sélectionné et je n'ai pas trouvé de méthode "clear" pour faire cela...

    Je te poste le code complet car je suis pas doué en C#, il se peut que j'ai mal codé...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    #region Références
    using System;
    using System.Windows.Forms;
    using System.Drawing;
    using System.ComponentModel;
    #endregion
     
    namespace TilePainter
    {
    	/// <summary>
    	/// Cette classe représente un PictureBox qui affiche en plus une grille par dessus l'image.
    	/// </summary>
    	public class GridPictureBox
    		: PictureBox
    	{
    		#region Variables locales
    		private Color		_GridColor;
    		private int			_GridWidth;
    		private int			_GridHeight;
    		private int			_GridSize;
            private int         _GridZoom; // facteur de zoom
            private bool        _GridLines; // indique si on veut ou pas le quadriage
            private bool        _GridHighlightSelected;
            private int         _GridHighlightSize;
            private Color       _GridHighlightColor;
            private Rectangle   _GridRectangleTemp; // variable temporaire pour l'élément sélectionné
    		#endregion
     
    		#region Propriétés
            /// <summary>
            /// Obtient ou définit si on souhaite mettre l'élément sélectionné en surbrillance
            /// </summary>
            [Category("Apparence"), Description("True si on souhaite mettre l'élément sélectionné en surbrillance."), DefaultValue(true)]
            public bool GridHighlightSelected
            {
                get { return _GridHighlightSelected; }
                set
                {
                    _GridHighlightSelected = value;
                    Invalidate();
                }
            }
     
            /// <summary>
            /// Obtient ou définit la taille de la bordule de l'élément sélectionné
            /// </summary>
            [Category("Apparence"), Description("La taille de la bordure de l'élément sélectionné."), DefaultValue(4)]
            public int GridHighlightSize
            {
                get { return _GridHighlightSize; }
                set
                {
                    _GridHighlightSize = value;
                    Invalidate();
                }
            }
     
            /// <summary>
            /// Obtient ou définit la couleur de la bordule de l'élément sélectionné
            /// </summary>
            [Category("Apparence"), Description("La couleur de l'élément sélectionné.")]
            public Color GridHighlightColor
            {
                get { return _GridHighlightColor; }
                set
                {
                    _GridHighlightColor = value;
                    Invalidate();
                }
            }
     
            /// <summary>
            /// Obtient ou définit le valeur du zoom de la grille
            /// </summary>
            [Category("Apparence"), Description("Le zoom de la grille.")]
            public int GridZoom
            {
                get { return _GridZoom; }
                set
                {
                    _GridZoom = value;
                    Invalidate();
                }
            }
     
            /// <summary>
            /// Obtient ou définit si la quadriage de la grille est visible ou pas.
            /// </summary>
            [Category("Apparence"), Description("Le quadriage de la grille.")]
            public bool GridLines
            {
                get { return _GridLines; }
                set
                {
                    _GridLines = value;
                    Invalidate();
                }
            }
     
            /// <summary>
    		/// Obtient ou définit la couleur de la grille.
    		/// </summary>
    		[Category("Apparence"), Description("La couleur de la grille.")]
    		public Color GridColor
    		{
    			get { return _GridColor; }
    			set
    			{
    				_GridColor = value;
    				Invalidate();
    			}
    		}
     
    		/// <summary>
    		/// Obtient ou définit l'espacement vertical de la grille.
    		/// </summary>
    		[Category("Apparence"), Description("L'espacement vertical de la grille."), DefaultValue(1)]
    		public int GridWidth
    		{
    			get { return _GridWidth; }
    			set
    			{
    				if (value < 1) throw new ArgumentException("L'espacement vertical de la grille ne peut être inférieur à 1.");
    				_GridWidth = value;
    				Invalidate();
    			}
    		}
     
    		/// <summary>
    		/// Obtient ou définit l'espacement horizontal de la grille.
    		/// </summary>
    		[Category("Apparence"), Description("L'espacement horizontal de la grille."), DefaultValue(1)]
    		public int GridHeight
    		{
    			get { return _GridHeight; }
    			set
    			{
    				if (value < 1) throw new ArgumentException("L'espacement horizontal de la grille ne peut être inférieur à 1.");
    				_GridHeight = value;
    				Invalidate();
    			}
    		}
     
    		/// <summary>
    		/// Obtient ou définit l'épaisseur des traits de la grille.
    		/// </summary>
    		[Category("Apparence"), Description("L'épaisseur de la grille."), DefaultValue(16)]
    		public int GridSize
    		{
    			get { return _GridSize; }
    			set
    			{
    				// La taille de la grille est un minimum 1
    				if (value < 1) throw new ArgumentException("L'épaisseur de la grille ne peut être inférieure à 1.");
    				_GridSize = value;
    				Invalidate();
    			}
    		}
    		#endregion
     
    		#region Constructeur
    		/// <summary>
    		/// Construit une GridPictureBox.
    		/// </summary>
    		public GridPictureBox()
    		{
    			_GridColor	= Color.Black;
    			_GridWidth	= 16;
    			_GridHeight = 16;
    			_GridSize	= 1;
                _GridLines = true;
                _GridZoom = 1;
                _GridHighlightSelected = true;
                _GridHighlightSize = 4;
                _GridHighlightColor = Color.Red;
    		}
    		#endregion
     
    		#region Méthodes
            protected override void OnClick(EventArgs e)
            {
                base.OnClick(e);
     
                if (this.Image != null)
                {
                    // Obtient la position du click
                    Point MousePosOnClick = this.PointToClient(Control.MousePosition);
     
                    // Si le click est dans l'image
                    if (MousePosOnClick.X < this.Image.Width && MousePosOnClick.Y < this.Image.Height)
                    {
                        // Calcul le rectangle du tile cliqué
                        int x = MousePosOnClick.X - (MousePosOnClick.X % this.GridWidth);
                        int y = MousePosOnClick.Y - (MousePosOnClick.Y % this.GridHeight);
                        Console.WriteLine(x);
                        Console.WriteLine(y);
                        _GridRectangleTemp = new Rectangle(x, y, this.GridWidth, this.GridHeight);
                        Invalidate(_GridRectangleTemp); // redessine le tile sélectionné
                    }
                }
            }
     
            protected override void OnPaint(PaintEventArgs pe)
    		{
    			// Dessine normale
    			base.OnPaint(pe);
     
    			// Maintenant que l'image est dessinée, on dessine la grille (a condition qu'une image soit affichée)
    			if(this.Image != null && _GridLines)
    			{
    				using (Pen p = new Pen(_GridColor, _GridSize))
    				{
    					// Dessine les lignes verticales
    					for(int i = 0; i < Image.Width; i += _GridWidth)
    					{
    						pe.Graphics.DrawLine(p, new Point(i, 0), new Point(i, Image.Height));
    					}
     
    					// Dessine les lignes horizontales
    					for (int j = 0; j < Image.Height; j += _GridHeight)
    					{
    						pe.Graphics.DrawLine(p, new Point(0, j), new Point(Image.Width ,j));
    					}
     
    					// Dessine le bord droit
    					pe.Graphics.DrawLine(p, new Point(Image.Width, 0), new Point(Image.Width, Image.Height));
     
    					// Dessine le bord du bas
    					pe.Graphics.DrawLine(p, new Point(0, Image.Height), new Point(Image.Width, Image.Height));
                    }
     
                    // dessine enfin le tile en surbrillance si demandé
                    if (_GridHighlightSelected)
                    {
                        using (Pen p = new Pen(_GridHighlightColor, _GridHighlightSize))
                        {
                            pe.Graphics.DrawRectangle(p, _GridRectangleTemp);
                            Console.WriteLine("rectangle dessine");
                        }
                    }
     
    			}
    		}
    		#endregion
    	}
    }
    Pour le Zoom, j'ai pas trop d'idée donc si tu pouvais m'aiguiller comme pour le tile sélectionné ca serait cool (pour moi un zoom change la taille de l'image... non ?)

    Merci ! et bonne soirée

  6. #26
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Il n'y a pas de méthode Clear. C'est à toi de gérer ca ^^'.
    C'est à dire que lorsqu'il se passe quelque chose comme par exemple un changement de taille de la grille ou un changement de tile sélectionné, tu dois mettre à jour ta variable locale qui indique le rectangle sélectionné, en la mettant à null s'il n'y a plus de sélection.
    Une fois la variable mise à jour tu dois alors appeler la méthode Invalidate() qui sert à provoquer le dessin complet du contrôle.

    Pour le zoom, non, comme je disais dans le post précédent, un zoom ne change pas la taille de l'image, mais seulement de son rendu. C'est comme dans la réalité, regarder la lune avec un télescope nous la fait apparaitre plus grosse, mais elle n'a pas changé de taille.

    La taille de l'image est donc : Image.Width * _GridZoom. (idem en hauteur).
    Et l'espacement entre les traits de la grille doit également être "zoomé" : _GridWidth * _GridZoom.

    Par contre, la plus grosse question que je me pose c'est qu'il me semble que le picturebox n'a pas de vrai notion de zoom.
    Le SizeMode.Zoom permet de mettre l'image aux dimension du PictureBox en conservant les proportion, ce qui semblerait convenir à un détail près :
    Le PictureBox est docké ou ancré, donc normalement il ne faut plus changer ses dimensions et celle-ci ne sont pas fixes. De plus le facteur de zoom n'est pas connus.
    Si tu changes les dimensions via width ou height puis que tu maximises la fenêtre, as-tu conserver les dimensions que tu avais définis ?
    Si non, tu ne peux donc pas te baser la dessus pour le dessin de la grille, le mieux étant de ré-écrire complètement un picturebox qui accepte une vrai notion de zoom.

  7. #27
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Ah ok ! J'avais fait une erreur en voulant gagner en optimisation :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Invalidate(_GridRectangleTemp); // redessine le tile sélectionné
    Mais en fait, il fallait redessiner toute la grille avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Invalidate(); // redessine la grille
    Et ca marche
    Pour le zoom, non, comme je disais dans le post précédent, un zoom ne change pas la taille de l'image, mais seulement de son rendu. C'est comme dans la réalité, regarder la lune avec un télescope nous la fait apparaitre plus grosse, mais elle n'a pas changé de taille.
    Oki avec cet exemple c'est clair

    Par contre pour le zoom, j'ai pas compris ta phrase :
    Le PictureBox est docké ou ancré, donc normalement il ne faut plus changer ses dimensions et celle-ci ne sont pas fixes. De plus le facteur de zoom n'est pas connus.
    Si tu changes les dimensions via width ou height puis que tu maximises la fenêtre, as-tu conserver les dimensions que tu avais définis ?
    De plus, les propriétés Width et Height de Image sont en readOnly, impossible de les modifiées... Je suppose qu'elles sont mises à jour automatiquement lorsqu'on assigne une nouvelle image via la propriété Image qui est en Read/Write...

    Je t'avoue que recoder une pictureBox avec un vrai zoom, je ne pense pas avoir le niveau... (à la base je suis codeur en C/C++ et j'avoue que j'ai du mal avec le C# pourtant c'est proche du C en syntaxe !).
    J'espère qu'il y a une solution car c'est tout ce qui me faut en plus pour la grille ^^

    J'ai tenté un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public int GridZoom
            {
                get { return _GridZoom; }
                set
                {
                    _GridZoom = value;
                    _GridHeight *= value;
                    _GridWidth *= value;
                    this.Width *= value;
                    this.Height *= value;
                    this.SizeMode = PictureBoxSizeMode.Zoom;
                    Invalidate();
                }
            }
    Mais ca ne fonctionne pas, la grille n'est pas correctement redessinée. Et c'est normal car tu utilises dans OnPaint, Image.Width et Image.Height pour dessiner la grille.

  8. #28
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    En fait, chaque contrôle (donc le PictureBox également) possède les propriétés suivantes :
    - Top
    - Left
    - Width
    - Height
    - Anchor
    - Dock

    Les deux premières permettent de positionner le coin supérieur gauche du contrôle dans le conteneur parent.
    Les deux suivantes indiquent la taille du contrôle (et non pas de l'image contenue dans le cas du PictureBox).
    Les deux dernières servent à recalculer automatiquement la position et la taille du contrôle quand la taille du conteneur parent change.
    Exemple :
    Met un bouton dans une fenêtre et définit sa propriété Dock à la valeur "Fill".
    Tu verra qu'en redimensionnant la fenêtre ca redimensionne également le bouton.
    Le Anchor ne fonctionne pas tout à fait pareil mais il final il influe également sur la dimension du contrôle.

    Du coup, la propriété SizeMode du PictureBox n'est pas adaptée ici puisque la taille du PictureBox n'est pas fixe, elle dépend de la taille de la fenêtre.

    Ré-écrire un picturebox capable de zoomer n'est pas si complexe dans la mesure où un picturebox n'est qu'un banal System.Windows.Forms.Control sur lequel on dessine une image.

    Donc tu pourrais partir d'un Control, ajouter les propriétés que tu veux (notamment le facteur de zoom et les propriétés déjà présentes concernant le dessin de la grille). Enfin, surcharger la méthode OnPaint pour y ajouter le dessin de l'image affectée.
    Tu trouvera dans Graphics toutes les méthodes qu'il faut pour dessiner l'image avec un zoom ou non.

  9. #29
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Oki merci, je vais voir ce que je peux faire.

    Par contre, j'ai déjà tenté par mal de fonction mais j'ai toujours une oréole de déformation autour des tiles lors du zoom, c'est normal ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Image bmp = new Bitmap(this.Width, this.Height);
                        using (Graphics g = Graphics.FromImage(bmp))
                        {
     
                            //g.SmoothingMode = SmoothingMode.AntiAlias;
                            //g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                            //g.PixelOffsetMode = PixelOffsetMode.HighQuality;
                            g.DrawImageUnscaledAndClipped(this.Image, new Rectangle(0, 0, this.Image.Width, this.Image.Height));
     
                            //g.DrawImage(this.Image, new Rectangle(0, 0, bmp.Width, bmp.Height), new Rectangle(0, 0, this.Image.Width, this.Image.Height), GraphicsUnit.Pixel);
                            //g.DrawImage(this.Image, 0, 0, bmp.Width, bmp.Height);
                            // Dessine l'ancienne image par dessus la nouvelle.
                            //g.DrawImageUnscaledAndClipped(this.Image, new Rectangle(0, 0, bmp.Width, bmp.Height));
     
                        }
    J'ai même trouvé une fonction sur le net :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    private Image ScaleByPercent(Image imgPhoto, int Percent)
            {
                float nPercent = ((float)Percent / 100);
     
                int sourceWidth = imgPhoto.Width;
                int sourceHeight = imgPhoto.Height;
                int sourceX = 0;
                int sourceY = 0;
     
                int destX = 0;
                int destY = 0;
                int destWidth = (int)(sourceWidth * nPercent);
                int destHeight = (int)(sourceHeight * nPercent);
     
                Bitmap bmPhoto = new Bitmap(destWidth, destHeight,
                                        PixelFormat.Format24bppRgb);
     
                bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);
     
                Graphics grPhoto = Graphics.FromImage(bmPhoto);
                grPhoto.InterpolationMode = InterpolationMode.HighQualityBilinear;
     
                grPhoto.DrawImage(imgPhoto,
                    new Rectangle(destX, destY, destWidth, destHeight),
                    new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight),
                    GraphicsUnit.Pixel);
     
                grPhoto.Dispose();
     
                return bmPhoto;
            }
    Pareil, ca déforme le contour des tiles...

  10. #30
    Membre expérimenté Avatar de ctxnop
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2007
    Messages
    858
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Morbihan (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2007
    Messages : 858
    Points : 1 732
    Points
    1 732
    Par défaut
    Tu pourrais montrer une capture de cette "auréole de déformation" ? Parce que je ne vois pas trop ce que tu veux dire par la.

  11. #31
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    Chose promise chose due.

    Ci-dessous le code permettant de copier une image dans une autre sans picturebox, uniquement en utilisant le system.drawing.imaging et le marshal copy de l'interop.

    J'ai fais le test avec collines.jpg réduite à 80*60 px, les fonctions scanalign, byteperscanline sont là uniquement pour être clair, on peu aussi verrouiller l'image source et définir l'image de destination dès le début et utiliser la valeur Stride du BmpData pour obtenir la même chose. Attention il faudrait optimiser la chose et prendre en compte les résidu lorsque l'image de destination n'a pas des dimensions qui sont un multiple des largeur et hauteur de l'image source mais bon il faut en laisser un peu à celui qui s'en servira ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    Imports System.Drawing.Imaging
    Public Class Form1
     
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Using Bmp As New Bitmap("C:\Collines.jpg")
                CopieImage(Bmp, 400, 300)
            End Using
        End Sub
     
        Public Sub CopieImage(ByVal BmpSource As Bitmap, ByVal Widthdest As Integer, ByVal HeigghtDest As Integer)
     
            'largeur de l'image alignée sur 32 bits
     
            Dim StrideDest As Integer = byteperscanline(Widthdest, BmpSource.PixelFormat)
     
            'Combien de fois on copie l'image en largeur et en hauteur
            Dim WS As Integer = byteperline(BmpSource.Width, BmpSource.PixelFormat)
     
            Dim Nw As Integer = StrideDest \ WS
     
            Dim Nh As Integer = HeigghtDest \ BmpSource.Height
     
            ' il faudrait gérer les relicats avec une fonction mod lorsque les largeur et hauteurs destination ne sont pas un multiple de l'origine
     
            'On dimensionne un tableau de largeur la destination de hauteur l'image origine
     
            Dim Band1 As Integer = StrideDest * BmpSource.Height
     
            Dim TabBand1(Band1 - 1) As Byte
     
            'On verouille le bitmap source
            Dim rect As New Rectangle(0, 0, BmpSource.Width, BmpSource.Height)
            Dim BmpData As BitmapData = BmpSource.LockBits(rect, ImageLockMode.ReadOnly, BmpSource.PixelFormat)
     
            'on obtient l'adresse de départ ligne 0
     
            Dim Ptr As IntPtr = BmpData.Scan0
            Dim ptrT As Integer
            'On définit la bande contenant nw fois l'image source
     
            For j = 0 To BmpSource.Height - 1
                'adresse de la ligne à copier
                ptrT = Ptr.ToInt32 + j * BmpData.Stride
                'on copie nw fois la  ligne
                For i = 0 To Nw - 1
                    System.Runtime.InteropServices.Marshal.Copy(ptrT, TabBand1, j * StrideDest + i * WS, WS)
                Next
            Next j
     
            'on deverouille
     
            BmpSource.UnlockBits(BmpData)
     
            'On définit le bitmap destination
     
            Using BmpDest As New Bitmap(Widthdest, HeigghtDest, BmpSource.PixelFormat)
     
                'on verouille le bitmap
                Dim rect1 As New Rectangle(0, 0, Widthdest, HeigghtDest)
                BmpData = BmpDest.LockBits(rect1, ImageLockMode.WriteOnly, BmpSource.PixelFormat)
                ' on récupère l'adresse de départ du tableau de bits de l'image
                Dim ptr1 As Integer = BmpData.Scan0
                'on copie la bande dans le nouveau bitmap
                Dim ptr2 As Integer
                For i = 0 To Nh - 1
                    ptr2 = ptr1 + i * Band1
                    System.Runtime.InteropServices.Marshal.Copy(TabBand1, 0, ptr2, Band1)
                Next
     
                ' on déverouille
                BmpDest.UnlockBits(BmpData)
                'on enregistre le bitmap
     
                BmpDest.Save("C:\Test.jpg")
     
            End Using
     
     
        End Sub
     
        Public Function scanalign(ByVal pwidth As Integer) As Integer
            scanalign = (pwidth + 3) And &HFFFFFFFC
        End Function
     
        Public Function byteperscanline(ByVal pwidth As Integer, ByVal bitcount As PixelFormat) As Integer
            Select Case bitcount
                Case PixelFormat.Format1bppIndexed
                    byteperscanline = scanalign((pwidth + 7) \ 8)
                Case PixelFormat.Format8bppIndexed
                    byteperscanline = scanalign(pwidth)
                Case PixelFormat.Format24bppRgb
                    byteperscanline = scanalign(pwidth * 3)
     
            End Select
        End Function
     
        Public Function byteperline(ByVal pwidth As Integer, ByVal bitcount As PixelFormat) As Integer
            Select Case bitcount
                Case PixelFormat.Format1bppIndexed
                    byteperline = (pwidth + 7) \ 8
                Case PixelFormat.Format8bppIndexed
                    byteperline = pwidth
                Case PixelFormat.Format24bppRgb
                    byteperline = pwidth * 3
     
            End Select
        End Function
     
    End Class

  12. #32
    Expert confirmé
    Avatar de Aspic
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2005
    Messages
    3 905
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Août 2005
    Messages : 3 905
    Points : 4 388
    Points
    4 388
    Par défaut
    Tiens voilà un exemple
    Oki, je vais voir l'autre proposition ^^
    Images attachées Images attachées  

  13. #33
    Membre averti
    Profil pro
    Inscrit en
    Février 2010
    Messages
    291
    Détails du profil
    Informations personnelles :
    Âge : 55
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 291
    Points : 390
    Points
    390
    Par défaut
    Bonjour,

    Un petit up car compte tenu des signatures des différents intervenants je me demandais si le sujet était résolu ....

  14. #34
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 442
    Points
    4 442
    Par défaut picturebox n'a pas de fonction zoom
    bonjour ctxnop
    cette phrase m'a intrigue "le picturebox n' a pas une fonction de zoom......".
    Il me semble que c'est valable pour tous les controles...
    Le probleme du zoom pour les images est qu'il faut pour les agrandir les "clipper" aux dimensions du controle conteneur & pour les retrecir il faut "retrecir" le controle pour les agrandir.
    Tout ceci n'etant pratiquable et pour cause .Leur taille qui est la taille disque.

    C'est pour cela qu'il faut passer par un tableau memoire comme le bmp,pour pouvoir travailler comme en "vectoriel".
    En vectoriel etant donne que c'est des "fonctions primitives" on peut redimensionner les figures,par rapport au controle fixe à tout instant.
    C'est pour cela qu'il faut defenir les fonctionnalites au depart ,sinon c'est du code sans fin.
    Bon code............

Discussions similaires

  1. Utilisation d'une image bitmap dans une DLL
    Par colorid dans le forum Débuter
    Réponses: 5
    Dernier message: 27/02/2009, 16h41
  2. copier une partie d'un fichier texte dans un autre
    Par Valarauko dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 23/10/2007, 22h17
  3. Réponses: 3
    Dernier message: 31/10/2006, 13h20
  4. [VBa-E] Object Ole "image bitmap" dans une Userform?
    Par gootsu dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 10/07/2006, 15h24
  5. Réponses: 6
    Dernier message: 22/12/2004, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo