[Tuto] Initiation au GDI+

Espace contenant des tutoriels divers concernant AutoIt.
Règles du forum
.

Tutoriel "La programmation avec Autoit" : https://openclassrooms.com/fr/courses/1 ... vec-autoit
Répondre
Avatar du membre
blacksoul305
Membre émérite
Membre émérite
Messages : 957
Enregistré le : ven. 18 mars 2011 11:49
Localisation : Au pays des programmeurs.
Status : Hors ligne

[Tuto] Initiation au GDI+

#1

Message par blacksoul305 » ven. 20 févr. 2015 15:25

Bonjour à tous,

depuis que je touche à AutoIt, j'essaye de me former sur tous les types de scripts que l'on peut faire avec ce langage. Script de gestion de fichiers, script réseau, avec ou sans interface graphique... mais jamais je n'ai eu l'audace de m'attaquer au GDI+...
Bien c'est décidé, je m'attaque (ou plutôt je me suis attaqué) à cela, et je compte bien vous partagez l'expérience que je vais acquérir au fur et à mesure.

Comme vous pouvez vous en douter, ce tutoriel va être assez spécial puisque je ne maîtrise pas parfaitement le GDI+ dans toutes ses fonctionnalités. Aussi je vais vous demander de partager vos codes, vos projets (touchant à une spécificité du GDI+) ou même vos idées, afin que je puisse quand le temps me le permet, les placer dans le tutoriel voir même leur attribuer une partie.

Donc, ce dont vous pouvez attendre de ce tutoriel, c'est d'apprendre à coder proprement en utilisant GDI+, assimiler les bases de tracer avec quelques fonctions essentiels et je l'espère, plus encore !

Si vous êtes partant pour vous plonger dans l'aventure de ce merveilleux monde du GDI+, armez-vous de votre SciTE et allons partager idées, codes et surtout... effroyables problèmes !

I) Qu'est-ce que GDI+ ?

Avant de programmer quoique ce soit avec, il vaudrait mieux commencer par un chapitre de présentation du GDI+.

GDI+ pour Graphic Design Interface Plus va nous permettre de manipuler des images, dessiner des traits, des courbes, des cercles, des arcs mais aussi du texte, dans nos applications. GDI+ est signé Windows dont les fonctions se trouvent dans gdiplus.dll.

Pour des informations plus précises, voir l'article dédié dans la MSDN.

Une fois bien maîtrisée, nous pourrons nous permettre beaucoup de folies notamment dans nos interfaces graphiques. En effet nous serons en mesure de modifier des images (couleurs, inclinaison) ou bien animer des dessins un peu comme les écrans de veilles, bref, tout ce que l'on pourrait imaginer... Le principal problème sera très certainement de réaliser nos idées plutôt que de les trouver !

II) Les choses à savoir pour débuter !

Pour mettre à profit ce que nous propose GDI+, il va nous falloir dans un premier temps, ressortir nos vieux cours de mathématiques de notre tête et placards.

1) Au niveau des maths :

Voici ce qu'il faut à tout prix savoir mathématiquement pour mieux appréhender GDI+ :
  • [IMPORTANT] Le plan : Un plan est dirigé par deux vecteurs directeurs (des flèches qui ne sont pas parallèles, qui se coupent à un endroit). Dans ce plan, pour pouvoir se repérer et y tracer des choses, on met en place un système de coordonnées.
    Ainsi, à chaque intervention nous aurons à référencer ces coordonnées qui sont les suivantes :
    x pour l'axe des abscisses (horizontal)
    y pour l'axe des ordonnées (vertical)
  • [IMPORTANT] Un point : Un point est un objet (qui sera représenté pour nous par un pixel) pouvant être placé dans un plan et défini par deux coordonnées notées (x;y)
  • [CONSEILLÉ] Un vecteur : Il s'agit d'un outil mathématiques représentant un déplacement. Un vecteur est défini par 4 choses :
    De coordonnées (x;y) : elles symbolisent un déplacement de x unités sur l'axes des abscisses et y unités sur l'axe des ordonnées, partant d'un point quelconque.
    D'une longueur : Qui est déterminée par la formule suivante : V(x²+y²) avec V pour racine carrée.
    D'une direction : Elle peut-être représentée par l'extension de part et autre de la flèche.
    D'un sens : Représenté par l'extrémité de la flèche.
Enfin, un vecteur peut être formé par deux points distincts (de coordonnées différentes) et est donné par la formule suivante : Soient A(Xa,Ya) et B(Xb,Yb), alors on a le vecteur AB(Xb-Xa,Yb-Ya).

Ci-dessous une image pour éclaircir un peu plus les choses.
► Afficher le texte
2) Au niveau du code

Le GDI+ n'étant pas inclus dans les fonctions primaires, il va falloir inclure le fichier GDIPlus.au3.
Aussi, l'objectif étant de programmer proprement, il faut donc savoir que le GDI+ va devoir être initialisé en début de script et arrêté en fin de script un peu comme le TCP/IP ou UDP.

Code : Tout sélectionner

_GDIPlus_Startup() ; autorise l'utilisation de GDI+
_GDIPlus_Shutdown() ; met fin à l'utilisation de GDI+
Pour dessiner nous allons avoir besoin de plusieurs choses :
  • Un plan, qui est appelé "Graphique" et que l'on créera tout simplement dans une GUI préalablement créée de dimensions quelconques.
  • D'un stylo d'une couleur quelconque
Attention, la plupart des objets créés et utilisés en GDI+ nécessite d'être détruit par la suite, comme l'on ferme un fichier avec FileClose que l'on a ouvert avec FileOpen.

Code : Tout sélectionner

;~ on suppose que $GUI est une fenêtre créée
_GDIPlus_Startup() ; on active GDI+
$graphicHdl = _GDIPlus_GraphicsCreateFromHWND($GUI) ; on créé le plan à partir de la fenêtre
$redPenHdl = _GDIPlus_PenCreate(0xFFFF0000) ; on créé un stylo rouge (couleur au format ARGB)
;~...
_GDIPlus_GraphicsDispose() ; on détruit le plan
_GDIPlus_PenDispose() ; on détruit le stylo
_GDIPlus_Shutdown() ; on arrête GDI+
Le format ARGB ou ARVB pour Alpha Rouge Vert Bleu est différent que d'habitude car là on gère la couche Alpha qui règle l'opacité. On pourra donc jouer sur des effets de transparence.

Vous pouvez maintenant partir sur un code propre de base, ci-dessous le mien.
► Afficher le texte
Vous voilà prêt pour la suite, maintenant il est temps de se compliquer la tâche !

III) Les fonctions essentielles de tracer !

Cette partie du tutoriel va être dédiée à ce qu'on pourrait appeler le dessin. En effet je vais essayer d'introduire un maximum de fonctions essentielles pour dessiner de choses simples, pour pouvoir par la suite, effectuer des choses plus complexes. On ne devrait pas avoir trop de soucis, la seule difficulté sera très probablement de savoir faire l'analogie entre un plan, notre interface de dessin, coordonnées et points etc...

1) Colorier un ou des pixels :

Comment changeons nous la couleur d'un pixel ?.. Bonne question. D'autant plus que cela peut s'avérer très utiles, en effet, une telle fonction pourrait nous permettre de pouvoir pointer des endroits dans notre GUI, pouvoir créer un logiciel de dessin pourquoi pas ?
Il est temps d'introduire notre première fonction de dessin :

Code : Tout sélectionner

_GDIPlus_GraphicsDrawRect( $hGraphics, $iX, $iY, $iWidth, $iHeight [, $hPen = 0] )
Voici les arguments que va prendre cette fonction :
  • $hGraphics : Vous l'avez très certainement compris, il s'agit du Handle du graphique que nous avons créé dans notre GUI.
  • $iX : Il va s'agir des coordonnées en X (abscisse ou encore axe horizontal) du point que vous voulez placer.
  • $iY : Il va s'agir des coordonnées en Y (ordonnée ou encore axe vertical) du point que vous voulez placer.
  • $iWidth : Pour colorier un pixel (ou groupe de pixels), il vous faudra systématiquement mettre '1' comme argument.
  • $iHeight : Pour colorier un pixel (ou un groupe de pixels), il vous faudra systématiquement mettre '1' comme argument.
  • $hPen : Tout comme pour le graphique, il est facile de comprendre que vous donnerez ici comme argument le Handle du stylo.
Alors je suppose que je vous dois quelques explications, nous ne colorions pas un pixel mais nous dessinons ("to draw" en anglais) un Rectangle (d'où le "Rec" dans le nom de la fonction).
Votre écran est composé de pixels, de très petits carrés ayant la caractéristique de pouvoir s'allumer de couleurs différentes, en combinant trois différentes couleurs : Rouge Vert Bleu. De plus, le GDI+ utilise par défaut le pixel comme unité. Maintenant vous devriez comprendre là où je veux en venir.
Dessiner un rectangle de longueur 1 pixel et de largeur 1 pixel, c'est tout simplement colorier un pixel.

Mais dans ces cas là, si je veux faire un point plus gros ? Et si je veux changer d'unité ? Il s'agit certainement d'une question que vous vous posez, bien c'est simple, pour y répondre, il faut jeter un oeil à notre stylo, car comme dans la réalité, notre stylo peut aussi avoir une mine de taille différente !

Code : Tout sélectionner

_GDIPlus_PenCreate ( [$iARGB = 0xFF000000 [, $iWidth = 1 [, $iUnit = 2]]] )
Détaillons les arguments que cette fonction prend en compte :
  • $iARGB : Vous savez déjà, la couleur voulue au format A[lpha]R[ouge]V[ert]B[leu]
  • $iWidth : la dimension de votre mine
  • $iUnit : L'unité à prendre en compte
Voici un exemple de code pratique, pour éviter de réécrire le code entièrement (et ainsi de trop surcharger le tutoriel), placer le petit bout ci-dessous dans le "Switch" du code donné dans la seconde partie.

Code : Tout sélectionner

Case -7 ; constante d'un clique gauche
_GDIPlus_GraphicsDrawRect($graphicHdl, $nMsg[3], $nMsg[4], 1, 1, $redPenHdl)
Ce code coloriera le pixel sur lequel vous aurez cliqué.

2) Tracer un segment :

Il est temps pour nous d'apprendre à tracer un segment. Certes ce n'est pas trop reluisant, mais à partir de plusieurs segments, il est possible de créer des formes ! Des triangles mais aussi des polygones. Je suis certain que vous trouverez un tas d'applications à cette fonction.
Il est donc temps d'accueillir notre seconde fonction de dessin !

Code : Tout sélectionner

_GDIPlus_GraphicsDrawLine ( $hGraphics, $iX1, $iY1, $iX2, $iY2 [, $hPen = 0] )
Faisons tout de suite un tour d'horizon sur ses paramètres :
  • $Graphics : vous commencez par vous y habituez.
  • $iX1 : Il va s'agir là des coordonnées en X du premier point
  • $iY1 : Il va s'agir là des coordonnées en Y du premier point
  • $iX2 : Il va s'agir là des coordonnées en X du second point
  • $iY2 : Il va s'agir là des coordonnées en Y du second point
  • $hPen : Le stylo vous le savez.
Nouveauté ici, il va vous falloir deux points, d'un autre côté, vous savez qu'un segment est délimité par deux points donc finalement rien de bien surprenant.

3) Tracer un rectangle :

Dans cette partie j'aimerais revenir à la fonction que nous avons tout juste utilisé pour colorier des pixels, mais cette fois-ci pour tracer un rectangle. Je vous représente notre fonction :

Code : Tout sélectionner

_GDIPlus_GraphicsDrawRect( $hGraphics, $iX, $iY, $iWidth, $iHeight [, $hPen = 0] )
Intéressons nous aux deux arguments que nous utilisions systématiquement à '1' :
  • $iWidth : Cela va être la longueur du rectangle que l'on va former.
  • $iHeight : Cela va être la largeur du rectangle que l'on va former.
Certes, il est intéressant de savoir faire un rectangle mais pour le moment, on ne sait faire que son contour. Sachez qu'il existe une fonction permettant de faire un rectangle plein. Et vous savez quoi ? Vous avez deux fonctions pour le prix d'une, elle est pas belle la vie ?
Alors pour utiliser :

Code : Tout sélectionner

GDIPlus_GraphicsFillRect ( $hGraphics, $iX, $iY, $iWidth, $iHeight [, $hBrush = 0] )
Il faudra utiliser :

Code : Tout sélectionner

_GDIPlus_BrushCreateSolid ( [$iARGB = 0xFF000000] )
Commençons donc par la brosse (brush en anglais).
La brosse est un objet, il va donc falloir la créer et la détruire. Elle prend comme argument uniquement une couleur au format ARGB.
La brosse va avoir un Handle, écrivons tout ça au même en droit où vous créez votre stylo :

Code : Tout sélectionner

$redBrushHdl = _GDIPlus_BrushCreateSolid(0xFFFF0000)
et écrivons ça à l'endroit où vous détruisez le stylo :

Code : Tout sélectionner

_GDIPlus_BrushDispose($redBrushHdl)
Vous avez donc créé votre pinceau avec succès !

Donc en ce qui concerne notre rectangle plein, la fonction ne change pas trop par rapport à un simple contour, vous devez simplement faire attention à passer le Handle de la brosse et non du stylo pour $hBrush.

4) Tracer une élipse :

L'élipse est la dernière partie qui compose notre chapitre sur les fonctions de tracé, pour la bonne et simple raison qu'après ça, vous saurez utiliser toutes les fonctions élémentaires de dessin. A partir de toutes ces fonctions, vous serez en mesure de dessiner des choses de plus en plus complexes à conditions de passer du temps avec.
Mais avant de passer la fonction en revue, parlons (très) légèrement des élipses.
Il existe plusieurs méthodes pour tracer une élipse, on peut passer par son équation, par un cercle directeur ou bien par un rectangle. Avec AutoIt, nous travaillerons avec le rectangle inscrit. En effet, la courbure de l'élipse se fera en fonction des dimensions de votre rectangle. Ci-dessous une image pour illustrer mon charabia.
► Afficher le texte
Remarque : les longueurs/largeurs du rectangle choisi pour chaque élipse sont indiquées en pixels.
De plus vous êtes capables de remarquer lorsque la longueur est égale à la largeur, on obtient un cercle parfait. Le cercle est donc un cas particulier de l'élipse.

Passons donc en revue la fonction :

Code : Tout sélectionner

_GDIPlus_GraphicsDrawEllipse ( $hGraphics, $iX, $iY, $iWidth, $iHeight [, $hPen = 0] )
Les arguments de notre fonction sont les suivants :
  • $hGraphics : vous connaissez la chanson.
  • $iX : L'abscisse du coin supérieur gauche du rectangle qui courbera l'élipse.
  • $iY : L'ordonnée du coin supérieur gauche du rectangle qui courbera l'élipse.
  • $iWidth : Longueur de ce rectangle.
  • $iHeight : Largeur de ce rectangle.
  • $hPen : Le handle de notre stylo.
Et bien sûr, tout comme le rectangle, on peut dessiner une élipse pleine. Il suffit d'appeler la fonction suivante :

Code : Tout sélectionner

_GDIPlus_GraphicsFillEllipse ( $hGraphics, $iX, $iY, $iWidth, $iHeight [, $hPen = 0] )
Dans ce cas, ne pas confondre votre stylo et votre brosse, car il vous faudra cette dernière pour utiliser cette fonction.

C'est terminé pour cette grande partie de dessin. Vous avez toutes les cartes en mains pour vous amusez un peu avec tout ça. La seconde partie portera sur la manipulation des images. Je ne sais pas encore comment tout va se passer puisque je n'ai pas encore essayé, mais une chose est sûre, les possibilités sont nombreuses, alors soyez patients !


IV) Manipulations du graphique et d'images

Comme vous l'avez compris, cette partie est entièrement consacrée à la manipulations des images et l'intégration de ces dernières dans nos interfaces graphiques. Cela va pouvoir nous donner de nombreuses possibilités, tant en matière de styles qu'en fonctionnalités. Si vous êtes prêts, alors n'attendons plus et parlons images !

1) Qu'est-ce qu'une image ?

Cette question peut vous paraître évidente, mais elle ne l'est pas tout à fait. Une image, quand vous l'affichez à l'écran, qu'est-ce que c'est ? Il s'agit tout simplement d'un agencement ordonné de pixels (vous vous rappelez de sa définition n'est-ce pas ?). L'image a une résolution (longueur et largeur) et une définition (longueur par largeur). Si la résolution est exprimée en pixels, alors la définition sera finalement le nombre de pixels qui composent l'image.

Une image peut être stockée dans votre ordinateur, ce n'est pas une surprise, tout comme le fait qu'il existe plusieurs extensions relatives aux images. En réalité, il existe deux types d'image :
  • Image
  • Bitmap
Et contrairement à ce que vous pourrez penser, le type Bitmap est celui que nous manipulons le plus au quotidien, et celui que nous manipulerons tout au long de cette partie.

Une image de type Bitmap est une image dite matricielle, c'est à dire que grosso modo, pour chaque pixel composant l'image, la couleur est donnée. Ainsi quand l'ordinateur doit dessiner l'image, il doit tout simplement mettre la couleur à la place qui lui est indiquée. Les images de ce type sont donc plus lourdes, et leur poids augmentera quand leurs définition augmentera.
Bien sûr, les formats évoluent et on a pu les « compresser » pour avoir une même (ou presque) qualité que les non compressées en gagnant de la place.

Quand aux Images, on appelle ça des images vectorielles. Les extensions, vous connaissez très certainement le .SWF mais il y a aussi le .EMF bref, je présume que vous ne les manipulez pas consciemment tous les jours. Le poids de ces images va varier selon la complexité à convertir l'image de façon mathématique (vectorielle). Typiquement, si vous avez l'image d'un cercle rouge sur fond blanc, l'image sera sans doute beaucoup moins lourde en format vectoriel que matriciel, car le cercle est un objet mathématiques que l'on peut construire « facilement » avec des vecteurs.

Attention, tout au long de ce tutoriel, j'utiliserai donc quelques abus de langage, notamment je confondrai dans les mots bitmap et image. Mais il faut bien avoir dans l'esprit que ces deux types d'images sont différents, et que ces derniers représentent des classes par la même occasion dans GDI+.

2) Dessiner une image :

Dans un premier temps, pour ceux qui n'ont pas lu la partie II de ce tutoriel, recopiez le code que j'ai proposé pour partir sur une base sûre. Pour les autres, conservez votre code.
La fonction qui va nous permettre de dessiner notre image est la suivante :

Code : Tout sélectionner

_GDIPlus_GraphicsDrawImage ( $hGraphics, $hImage, $iX, $iY )
Pour pouvoir l'utiliser il nous faudra utiliser :

Code : Tout sélectionner

_GDIPlus_BitmapCreateFromFile ( $sFileName )
ou

Code : Tout sélectionner

_GDIPlus_ImageLoadFromFile ( $sFileName )
En fait, ça pourrait sembler contradictoire par rapport à ce que j'ai dit, mais il faut savoir que GDI+ a été développé par Microsoft, et si le principe n'est pas explicite en AutoIt, Image et Bitmap sont en fait ce que l'on appelle des classes, au même titre que Graphic. La classe Image (donc les fonctions commençant par _GDIPlus_Image...) gère les images vectorielles mais aussi les bitmaps. En revanche le phénomène n'est pas réciproque. De plus, la classe Bitmap nous offre bien plus de possibilités que la classe Image en ce qui concerne les "raster images". Nous n'en verrons certainement pas toute l'étendue de ces possibilités puisqu'il s'agit d'un tutoriel d'initiation, mais c'est un atout qu'il faut mettre en avant. C'est pourquoi j'utiliserai plus la classe Bitmap que Image tout au long de ce tutoriel.

Avant que vous ne vous hâtiez dans votre document "Mes Images" et que vous choisissiez celle que vous dessinerez dans votre fenêtre, il faut quand même que je vous prévienne : au même titre que la plupart des outils que nous avons manipulés jusqu'à maintenant, les images et les bitmaps sont des objets que l'on crée et que l'on détruit. C'est à dire avec :

Code : Tout sélectionner

_GDIPlus_BitmapDispose ( $hBitmap )
et :

Code : Tout sélectionner

_GDIPlus_ImageDispose ( $hImage )
respectivement.

Pour synthétiser tout ça, faisons un rapide tour de ces fonctions et leurs arguments.
  • $sFileName : Il s'agit du chemin complet de l'image, c'est à dire de la racine jusqu'à son nom comprenant son extension. Il est bien évidemment possible de construire avec des macros comme @ScriptDir par exemple.
  • $hBitmap : Il s'agit du handle d'un bitmap que vous avez créé. Ce dernier est renvoyé par la fonction _GDIPlus_BitmapCreateFromFile dans notre exemple.
  • $hImage : Il s'agit du handle d'une image que vous avez créée, et qui est renvoyé par la fonction _GDIPlus_ImageLoadFromFile
  • $iX et $iY : Vous commencez à vous habituez de ces coordonnées, dans notre exemple elles représenteront l'endroit où l'on dessinera le coin supérieur gauche de l'image. En (0 ; 0), vous dessinerez l'image à partir du coin supérieur gauche de votre fenêtre.
Vous pouvez dorénavant tester ces fonctions, et je vous invite à charger une même image par la classe Image et la dessiner dans votre graphique avec la fonction de la même classe, et ensuite charger votre même image mais avec la classe Bitmap puis la dessiner avec la fonction de la classe Image pour vérifier que vous pouvez bel et bien faire les deux.

3) Cloner une image chargée, dessiner une portion d'image :

Ici, il va être question de ne plus dessiner une image mais d'en dessiner une portion. Aussi, il nous sera utile pour plus tard de savoir comment cloner une image pour pouvoir par exemple modifier et afficher son clone, plutôt que de modifier l'image originale et de la recharger à chaque fois que l'on ne veut plus tenir compte des modifications opérées.
Ci-dessous, deux fonctions de clonage :

Code : Tout sélectionner

_GDIPlus_BitmapCreateFromHBITMAP ( $hBitmap [, $hPal = 0] )
_GDIPlus_BitmapCloneArea ( $hBitmap, $iLeft, $iTop, $iWidth, $iHeight [, $iFormat = 0x00021808] )
Ces deux fonctions étant des fonctions de clonage, elles renvoient toutes deux des handle de bitmaps et donc nécessitent d'être détruites à la fin de leur utilisation avec :

Code : Tout sélectionner

_GDIPlus_BitmapDispose ( $hBitmap )
Regardons dès à présent la liste des arguments :
  • $hBitmap : celui-ci n'a plus aucun secret pour vous, il s'agit du handle d'un Bitmap, qui peut être donné par un _GDIPlus_BitmapCreateFromFile, _GDIPlus_BitmapCreateFromHBITMAP ou bien encore _GDIPlus_BitmapCloneArea.
  • $iLeft : cet argument demande de combien de pixels doit se décaler vers la gauche la fonction pour commencer à copier (coordonnée en x dans l'image du point gauche supérieur du rectangle)
  • $iTop : cet argument demande de combien de pixels doit se décaler vers le bas la fonction pour commencer à copier (coordonnée en y dans l'image du point gauche supérieur du rectangle)
  • $iWidth : représente la longueur en pixels du rectangle de sélection de l'image à cloner
  • $iHeight : représente la largeur en pixels du rectangle de sélection de l'image à cloner
  • $hPal et $iFormat : je ne donnerai pas d'information sur ces arguments car je n'en ai pas encore trouvé une définition et utilité exacte. Par défaut, le format donné par $iFormat représente la constante $GDIP_PXF24RGB. Voir le fichier aide pour _GDIPlus_BitmapCloneArea et le fichier include GDIPlusConstants.
Remarque : Il est possible de cloner entièrement un bitmap comme ceci :

Code : Tout sélectionner

$hBitmap = _GDIPlus_BitmapCreateFromFile($sFileName)
$hClone = _GDIPlus_BitmapCloneArea($hBitmap, 0, 0, _GDIPlus_ImageGetWidth($hBitmap), _GDIPlus_ImageGetHeight($hBitmap))
_GDIPlus_BitmapDispose($hBitmap)
_GDIPlus_BitmapDispose($hClone)
Ce code vous montre au moins deux choses : il vous présente deux fonctions qui permettent de récupérer la taille d'une image en pixels et qui en plus de cela appartiennent à la classe image mais que l'on peut utiliser avec un handle de bitmap malgré tout.

Bref, vous pouvez maintenant dessiner à l'aide de la fonction _GDIPlus_GraphicsDrawImage votre image, votre clone. Aussi, vous n'êtes pas obligé de ne copier qu'un rectangle, en utilisant des astuces comme l'on faisait en début de tutoriel avec _GDIPlus_GraphicsDrawRec, il est facile de copier un pixel spécifique d'une image, une ligne de pixel, une colonne etc...

Code : Tout sélectionner

$hClone = _GDIPlus_BitmapCloneArea($hBitmap,50,78,1,1) ; pixel de coordonnées (50 ; 78) dans l'image
$hClone = _GDIPlus_BitmapCloneArea($hBitmap,0,10,_GDIPlus_ImageGetWidth($hBitmap),1) ; dixième ligne de pixels de l'image
$hClone = _GDIPlus_BitmapCloneArea($hBitmap,2,0,1,_GDIPlus_ImageGetHeight($hBitmap)) ; deuxième colonne de pixels de l'image
4) Graphique d'une taille personnalisée :

Jusqu'à présent, pour créer notre zone de dessin, nous prenions notre GUI entière. Or, la plupart de nos programmes utilisent des GUI assez développées et qui contiennent donc des champs, des groupes, des arbres et j'en passe... en effet, si on veut dessiner sur une portion de la GUI, il paraît plus judicieux de créer un graphique à notre guise, plutôt que de finalement devoir dessiner manuellement des contrôles etc...

Comment fait-on ? Bien d'abord il nous faut un "control", un élément dans la GUI que l'on va "transformer" en zone de dessin, ou en tout cas sur le quel on appliquera une zone de dessin. Il est conseillé de prendre une image vide, mais sachez qu'il est aussi possible de prendre un bouton par exemple.
Ensuite, il faut récupérer le "handle" de l'élément créé. Et on passe tout simplement ce "handle" ci à la fonction qui crée le graphique plutôt que celui de la fenêtre. Ci-dessous un code qui fait tout ça, bon je ne me suis pas foulé stylistiquement parlant, mais ça fait ce que l'on veut, et c'est propre !
► Afficher le texte
Voilà, certes cette partie est relativement courte, en revanche vous êtes désormais capable d'utiliser GDIPlus de façon non invasive dans vos fenêtres, ce qui est une assez bonne chose !

5) Du graphique au bitmap et du bitmap au fichier :

Qui à ses débuts dans l'ordinateur n'a jamais ouvert un logiciel tel que paint, fait un dessin, l'a sauvegardé puis la ré-ouvert un moment après ? Vous vous souvenez de votre graphique depuis le début du tutoriel, que vous créez, sur lequel vous dessinez, effacez puis qu'à la fin vous détruisez ? Hé bien il est possible d'en obtenir un handle de bitmap. Et vous savez quoi ? Il est également possible de créer une image à partir d'un bitmap. Ci-dessous une de mes créations !
► Afficher le texte
En fait, la fonction nous permettant cela est beaucoup moins simple qu'il n'y paraît, et en plus de cela elle ne vient pas de moi. La fonction ci-dessous vient du membre UEZ du forum US et qui m'a aidé petit à petit à créer ce tutoriel. J'essayerai de la décrire en détails, mais seulement une fois que j'aurais compris comment cette dernière fonctionne exactement.
► Afficher le texte
Alors comment utiliser cette fonction ? C'est simple, beaucoup plus que d'essayer de la comprendre c'est certain, mais il y a un piège. Listons ses arguments :
  • $hWnd : Alors, quel handle on vous demande ici ? Celui du graphique ? *buzz* Perdu ! En fait, le handle du graphique vous permet de dessiner, de faire plein de choses, mais il ne conserve aucune trace de dessins. L'élément dont on demande le handle est celui sur lequel vous avez fixé votre graphique. Ainsi, si vous avez utilisé le handle de votre GUI, alors ça sera celui-ci a passé en argument, si vous avez passé celui d'une image, ou d'un bouton, bien ce sera lui et non la GUI a passé en argument.
  • $iWidth/$iHeight : Ce coup-ci pas de pièges, il s'agit de la taille de l'image que vous voulez créer, mais vu que vous avez en tête de sauvegarder votre graphique, il faut donner ses dimensions.
  • $sFileName : Le chemin et le nom de votre image, sans oublier l'extension : .jpg, .bmp ou encore .png par exemple.
De sa fonction, on peut en créer une autre pour n'obtenir que le bitmap du graphique. Et donc pouvoir redessiner le graphique à l'identique au cas où. Typiquement, il arrive que si vous réduisez la fenêtre, le graphique se retrouve effacé lorsque vous la remettez en premier plan. Si vous avez sauvegardé auparavant le graphique, alors il vous est possible de le redessiner ! Je vous évite les modifications, cadeau !
► Afficher le texte
Attention, cette fonction utilise des fonctions du type _WinAPI_... ce qui implique qu'il fait inclure le fichier "WinAPI.au3" dans votre programme, de plus elle renvoie un bitmap, ça veut dire qu'il faut nécessairement le détruire, soit à la fin du script, soit après son utilisation, car vous risquez de grignoter beaucoup de mémoires à la longue.

En résumé, pour obtenir un bitmap à partir du graphique, il faut utiliser la fonction ci-dessus. Et pour créer un fichier, à partir d'un bitmap, il faut utiliser la fonction :

Code : Tout sélectionner

_GDIPlus_ImageSaveToFile ( $hImage, $sFileName )
Ce qui conclue cette partie !

Oh non... c'est déjà la fin ! Oui mais non, c'est seulement la fin de cette grande partie. L'idée était de vous initier à la manipulation des images, des bitmap et du graphique. Mine de rien, vous êtes capables d'un tas de choses, rien qu'en arrivant ici dans ce tutoriel. Vous savez dessiner à la fois des formes, mais des images et donc dans des images. Avec ça, il y a un tas de projets intéressants qui peuvent pointer le bout de leur nez.

Donc comme vous l'avez compris, le tutoriel n'est pas encore terminé. Il y a un dernier aspect que j'aimerais voir, il s'agit de l'écriture de texte et la manipulation avancées des bitmap, permettant d'appliquer des effets... Je pense que c'est possible mais je n'ai encore rien pratiqué donc mystère ! J'espère que ce qui est présent ci-dessus vous a néanmoins aidé.

Je remercie UEZ et mikell pour l'aide à l'élaboration de ce tutoriel, qui n'est pas encore terminé ! ;)
Modifié en dernier par blacksoul305 le dim. 22 mars 2015 15:35, modifié 3 fois.
Étudiant en 2ème année de Licence Informatique.

Avatar du membre
jbnh
Modérateur
Modérateur
Messages : 1932
Enregistré le : ven. 02 mai 2008 13:54
Localisation : Bruxelles
Contact :
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#2

Message par jbnh » ven. 20 févr. 2015 17:26

Super :)

Grand merci pour cette contribution
Balise [..] devant votre requête en cours, [R] quand résolu | Pas de message concernant les bots !

Merci

Avatar du membre
mikell
Modérateur
Modérateur
Messages : 5780
Enregistré le : dim. 29 mai 2011 16:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#3

Message par mikell » ven. 20 févr. 2015 19:02

Super début
J'attends avec une impatience fébrile les définitions/explications sur les différences entre graphic, image, bitmap et autres hbitmap et hHbitmap forts générateurs de céphalées :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )

Avatar du membre
jguinch
Modérateur
Modérateur
Messages : 2469
Enregistré le : lun. 14 févr. 2011 22:12
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#4

Message par jguinch » ven. 20 févr. 2015 22:07

Merci Blacksoul pour ce tuto très bien fait !
Perso je suis une quiche en GDI, je trouve ça très intéressant.
J'attends la suite avec impatience !
Le script, ça fait gagner beaucoup de temps... à condition d'en avoir beaucoup devant soi !

Avatar du membre
blacksoul305
Membre émérite
Membre émérite
Messages : 957
Enregistré le : ven. 18 mars 2011 11:49
Localisation : Au pays des programmeurs.
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#5

Message par blacksoul305 » ven. 20 févr. 2015 23:34

Bonsoir et merci à tous pour ces remontées très positives, ça fait plaisir.

Oui Mikell, j'dois t'avouer que ça me fait un peu peur tout ça vu que j'n'ai jamais contrôlé ces bébêtes là, mais j'ai plein d'idées en tête donc ça devrait aller ! Puis comme le souligne jguinch, il y a pas mal de manipulations intéressantes à faire sur des images notamment, c'est pourquoi j'compte y dédier une partie.
Étudiant en 2ème année de Licence Informatique.

Avatar du membre
mikell
Modérateur
Modérateur
Messages : 5780
Enregistré le : dim. 29 mai 2011 16:32
Localisation : Deep Cévennes
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#6

Message par mikell » sam. 21 févr. 2015 18:53

Franchement je pense que le plus dur c'est d'assimiler les finesses des différents éléments mentionnés dans mon post précédent
Si tu rames et pour gagner du temps tu pourrais éventuellement demander à UEZ sur le forum US, c'est un grand spécialiste qui a fait des scripts ébouriffants et qui sait de quoi il parle, exemple les commentaires dans ce petit post
Cela dit tu t'es attaqué à un gros morceau

Edit
Je te recommande de jeter un oeil à ce site très documenté et qui a aussi l'avantage (non négligeable en l'occurence) d'être en français :mrgreen:
" L'échec est le fondement de la réussite. " (Lao-Tseu )
" Plus ça rate, plus on a de chances que ça marche " (les Shadoks )

Avatar du membre
blacksoul305
Membre émérite
Membre émérite
Messages : 957
Enregistré le : ven. 18 mars 2011 11:49
Localisation : Au pays des programmeurs.
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#7

Message par blacksoul305 » sam. 21 févr. 2015 19:01

Bonsoir mikell,

j'te remercie pour tes liens, ils risquent de beaucoup m'aider pour la rédaction de cette partie.
Je m'en suis rendu compte déjà (de la difficulté), j'viens de commencer la partie et rien que définir précisément ce qu'est un bitmap est quelque chose de non aisée. Bref, j'ai du boulot et la partie est loin d'être finie.
L'idée étant de donner des bases sur le GDI+, même s'il s'agit seulement d'une initiation, mais au moins qu'elles soient solides, sur lesquelles on peut s'appuyer si l'on veut aller plus loin, et vu que c'est mon but... j'vais essayer de faire quelque chose de cohérent.

Merci !
Étudiant en 2ème année de Licence Informatique.

Avatar du membre
blacksoul305
Membre émérite
Membre émérite
Messages : 957
Enregistré le : ven. 18 mars 2011 11:49
Localisation : Au pays des programmeurs.
Status : Hors ligne

Re: [Tuto] Initiation au GDI+

#8

Message par blacksoul305 » dim. 22 mars 2015 15:22

Bonjour à tous,

je me permets d'écrire un message pour avertir les personnes qui attendaient la partie portant sur les images qu'elle est enfin terminée et disponible ! Cette dernière s'intitule : Manipulations du graphique et d'images, et constitue la partie IV de ce tutoriel, merci à ceux qui la liront.
Étudiant en 2ème année de Licence Informatique.

Avatar du membre
DimVar
Niveau 10
Niveau 10
Messages : 742
Enregistré le : ven. 30 mai 2008 14:08
Status : En ligne

Re: [Tuto] Initiation au GDI+

#9

Message par DimVar » jeu. 16 juil. 2015 09:05

Je passais par là, et je félicite le travail effectué.
Chapeau !
N'évoquons pas la pierre, les jeunes risqueraient d'en poire !

Répondre