Bonjour,
Je travaille sur un programme qui permet aux utilisateurs d'ajouter des informations sur des images chargées dans mon application. C'est à dire que j'affiche ces images (ici ce sont des pages scannées) sous la forme de picturebox (1 par page) comme dans un document Word. Ensuite l'utilisateur peut ajouter des textes par dessus.

Mon problème est le suivant, à l'impression de mon document j'ai parfois (pour des gros documents) des messages d'erreur "Mémoire insuffisante". Je vois bien que même en disposant de tout mes objets, la mémoire allouée au programme grandis à chaque page envoyée à l'impression. Je procède comme suite pour imprimer ces picturebox :

1. Je stock l'image actuelle de la Picturebox
2. J'applique à ma picturebox la taille de l'image (stockée) à 300dpi et j'agrandis ma picturebox pour la mettre aux même dimensions.
3. Je fais un "InvokePaint" sur ma PictureBox pour dessiner les textes sur l'image à 300dpi et dessiner directement sur mon control d'impression
4. Je rétabli la taille et l'image de ma PictureBox
5. Je dispose des images + graphics
6. Et je passe à la page suivante.

Voici un aperçu (un peu simplifié) de ma page d'impression (se trouve dans l'événement "PrintDocument.PrintPage").

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
Using g As Graphics = e.Graphics
                'On récupère la page courante comme page à imprimer
                Dim PageNumber As Integer = Form1.panel_scrollNavigator.Controls.GetChildIndex(PagesToPrint(nbSheets))
                'On récupère le control
                Dim ctrl As Page = Form1.panel_scroll.GetPage(PageNumber + 1)
                'Niveau de détail du texte
                g.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
                'On charge l'image en cours
                Dim img As System.Drawing.Bitmap = CType(Image.FromFile(Form1.TempPath + "\" + ctrl.Name + ".png"), Bitmap)
                'On récupère la taille actuel du control
                Dim ctrlW As Integer = ctrl.Width
                Dim ctrlH As Integer = ctrl.Height
                'On défini les bordures de la page
                Dim pageBorder As New Rectangle(e.PageBounds.Left, e.PageBounds.Top, e.PageBounds.Width, e.PageBounds.Height)
                'On défini le nouveau ratio de la page pour l'impression des textes
                Form1.ratio = CSng(System.Math.Sqrt(System.Math.Pow(img.Height, 2) + System.Math.Pow(img.Width, 2)) / _
                System.Math.Sqrt(System.Math.Pow(ctrl.Height, 2) + System.Math.Pow(ctrl.Width, 2)))
                'On défini la taille du control à la même taille que l'image (300 dpi)
                ctrl.Width = img.Width
                ctrl.Height = img.Height
                'On lui applique l'image à 300 dpi comme image de fond
                ctrl.Image = CType(img.Clone, Image)
                'Ici on dessine l'image en 300 dpi redimenssionnée aux dimensions des pages
                g.DrawImage(img, 0, 0, ctrl.Width, ctrl.Height)
                'Ensuite on créé un bitmap et un graphics temporaire pour stocker le dessin du texte en 300 dpi
                Dim bmp As New Bitmap(img.Width, img.Height)
                Dim gimg As Graphics = Graphics.FromImage(bmp)
                Dim PArgs As New PaintEventArgs(gimg, New Rectangle(img.Width, img.Height, img.Width, img.Height))
                'On fait un InvokePaint sur le graphic temporaire pour dessiner le control
                InvokePaint(ctrl, PArgs)
                'Et on dessine le texte sur le page actuel
                g.DrawImage(bmp, 0, 0, g.VisibleClipBounds.Width, g.VisibleClipBounds.Height)
 
                'Puis on remet le control à sa taille d'origine
                ctrl.Width = ctrlW
                ctrl.Height = ctrlH
                'Et on retrouve l'image de base
                bmp = New Bitmap(ctrl.Width, ctrl.Height)
                gimg = Graphics.FromImage(bmp)
                'Et on l'applique au control
                gimg.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
                gimg.DrawImage(ctrl.Image, 0, 0, ctrl.Width, ctrl.Height)
                ctrl.Image = CType(bmp.Clone, Image)
                ctrl.SizeMode = PictureBoxSizeMode.Normal
                'Puis on dispose de tout ce petit monde
                gimg.Dispose()
                img.Dispose()
                bmp.Dispose()
                gimg = Nothing
                img = Nothing
                bmp = Nothing
 
                GC.Collect()
 
                If nbSheets = pdi.PrinterSettings.ToPage - 1 Then
                    hasMorePages = False
                    e.HasMorePages = False
                Else
                    nbSheets += 1
                    hasMorePages = True
                    e.HasMorePages = True
                End If
 
End Using
Y a t'il des problèmes de fuites de mémoires sur les picturebox ? Logiquement le fait que je modifie ma Box pour prendre des valeurs supérieures pour l'impression et qu'ensuite je remet celle-ci à son état d'origine ne devrait pas augmenter la mémoire allouée au programme non ? (enfin si, pendant le processus, mais pas après)

Merci de votre aide