Bonjour,
Je veux créer une carte (de wargame) avec une grille hexagonale et la sauvegarder sur disque en jpg.
J’ai créé une classe hexPicturebox qui hérite de Picturebox et qui dessine un hexagone. Là n’est pas le problème, çà fonctionne bien. J’arrive à créer ma carte… à l’écran (fig 1). Ces hex sont ajoutés avec leurs propriétés dans une picturebox (pbMap), elle-même insérée dans une form (F_Map) pour pouvoir la déplacer sur l’écran (voir code ci-dessous)
Là où çà se gâte c’est quand je veux transformer çà en image pour pouvoir la sauvegarder.
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 Private Sub F_Map_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load ratioScreen = F_Start.tbRatio.Text / 100 Me.Location = New Point(50 + F_Start.Width + 50, 50) Dim nc As Integer = F_Start.tbCol.Text Dim nl As Integer = F_Start.tbRow.Text Dim ux As Single = F_Start.tbDim.Text / 2 'unité x Dim uy As Single = ux * Math.Cos(30 * Math.PI / 180) 'unité y 'taille de la picturebox de la carte Hmap = 2 * uy + nl * 4 * uy If nc Mod 2 = 0 Then Wmap = 4 * ux * (nc \ 2) + ux * (nc + 1) Else Wmap = 6 * ux * (nc \ 2) + 4 * ux End If pbMap.Location = New Point(0, 0) pbMap.Size = New Size(Wmap + 2, Hmap + 2) pbMap.BackColor = Color.Transparent pbMap.BorderStyle = BorderStyle.FixedSingle Me.ControlBox = True Me.FormBorderStyle = FormBorderStyle.FixedToolWindow Me.AutoSize = True Me.Size = pbMap.Size For r = 0 To nl - 1 For c = 0 To nc - 1 Dim hex As New HexPicturebox hex.Name = c.ToString("00") & r.ToString("00") hex.Tag = c.ToString("00") & r.ToString("00") If c Mod 2 = 0 Then hex.Location = New Point(6 * ux * (c \ 2), r * 4 * uy) Else hex.Location = New Point(3 * ux + 6 * ux * (c \ 2), 2 * uy + r * 4 * uy) End If hex.Size = New Size(4 * ux, 4 * uy) hex.BackgroundImage = Image.FromFile(imageNormHex) hex.BackgroundImageLayout = ImageLayout.Stretch hex.Visible = True AddHandler hex.Click, AddressOf hex_Click AddHandler hex.MouseMove, AddressOf hex_MouseMove pbMap.Controls.Add(hex) Next Next End Sub
J’ai entrevu 3 possibilités, qui ne me satisfont ni les unes ni les autres :
Les 3 solutions qui suivent sont dans une Private sub
car je veux utilizer la « croix » de la barre de titre de la form F_Map pour sauvegarder mon image
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Private Sub Clic_Croix(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing end sub
Solution 1
Cà fonctionne quelle que soit la résolution d’écran Mais le résultat est dégueulasse (fig 2)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 Dim ficMap As String = F_Start.tbFile.Text carte = New Bitmap(pbMap.Width, pbMap.Height) pbMap.DrawToBitmap(carte, New Rectangle(0, 0, pbMap.Width, pbMap.Height)) carte.Save(ficMap, System.Drawing.Imaging.ImageFormat.Jpeg)
Solution 2
Là, le fichier de sauvegarde me donne une carte noire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Dim ficMap As String = F_Start.tbFile.Text carte = New Bitmap(pbMap.Width, pbMap.Height) carte.Save(ficMap, System.Drawing.Imaging.ImageFormat.Jpeg)
Solution 3
Avec
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Dim ficMap As String = F_Start.tbFile.Text CaptureCtrl(Me).Save(ficMap, System.Drawing.Imaging.ImageFormat.Jpeg) Me.Dispose()
Ici, le résultat est joli (comme à l’écran, fig 3) mais si je change la résolution d’écran tout est foutu. La capture n’est plus du tout ce qu’il faut : elle a toujours la même taille mais est complètement décalée et donc ne représente plus la bonne image.
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 Function CaptureCtrl(ByVal ctrl As Control) As Bitmap bordureX = GetSystemMetrics(32) 'SM_CXFRAME bordureY = GetSystemMetrics(33) 'SM_CYFRAME hBarreTitre = bordureY * 4 Dim W As Integer = ctrl.Width * ratioScreen Dim H As Integer = ctrl.Height * ratioScreen Dim L As Integer = ctrl.Left * ratioScreen Dim T As Integer = ctrl.Top * ratioScreen Dim wBitmap As Integer = W - 2 * bordureX + 4 Dim hBitmap As Integer = H - (hBarreTitre + bordureY) Dim chgX As Integer = L + bordureX - 2 Dim chgY As Integer = T + hBarreTitre + 2 Dim bmpSS As Bitmap Dim gfxSS As Graphics bmpSS = New Bitmap(wBitmap, hBitmap, System.Drawing.Imaging.PixelFormat.Format32bppArgb) gfxSS = Graphics.FromImage(bmpSS) gfxSS.CopyFromScreen(New Point(chgX, chgY), New Point(0, 0), New Size(wBitmap, hBitmap), CopyPixelOperation.SourceCopy) gfxSS.Dispose() Return bmpSS End Function
P.S : F_Start est le formulaire qui détermine les caractéristiques de la carte (nombre de col, lignes, dim d’un hex, image de fond d’un hex (imageNormHex)… ainsi que le ratioScreen (échelle d’écran définie dans les paramètres affichage de windows)
P.S2 : Fig1 en haut à gauche, fig 2 en haut à droite, fig 3 en bas
Si quelqu’un a une idée pour obtenir le résultat souhaité pour une des solutions, je lui en serais éternellement reconnaissant
Merci.
Partager