3 pièce(s) jointe(s)
Problème de sauvegarde d'image sur disque
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)
Code:
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 |
Là où çà se gâte c’est quand je veux transformer çà en image pour pouvoir la sauvegarder.
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
Code:
1 2 3
| Private Sub Clic_Croix(ByVal sender As Object, ByVal e As FormClosingEventArgs) Handles Me.FormClosing
end sub |
car je veux utilizer la « croix » de la barre de titre de la form F_Map pour sauvegarder mon image
Solution 1
Code:
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) |
Cà fonctionne quelle que soit la résolution d’écran Mais le résultat est dégueulasse (fig 2)
Solution 2
Code:
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) |
Là, le fichier de sauvegarde me donne une carte noire
Solution 3
Code:
1 2 3
| Dim ficMap As String = F_Start.tbFile.Text
CaptureCtrl(Me).Save(ficMap, System.Drawing.Imaging.ImageFormat.Jpeg)
Me.Dispose() |
Avec
Code:
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 |
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.
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.