Background: Je travaille sur une application silverlight (1.0) qui construit dynamiquement une carte des États-Unis avec des icônes et du texte superposés à des endroits spécifiques. La carte fonctionne très bien dans le navigateur et maintenant je dois obtenir une copie statique (imprimable et insérable dans les documents/powerpoints) d'une carte affichée.Mise à l'échelle du contenu WPF avant le rendu en bitmap
Objectif: Afin d'obtenir une copie imprimable de la carte qui peut également être utilisée dans les diapositives Powerpoint, Word, etc. WPF et ensuite rendre le WPF à une image bitmap qui est retournée en tant que fichier png, généré à 300 dpi pour une meilleure qualité d'impression.
Problème: Cela fonctionne très bien avec un problème, je ne peux pas obtenir l'image à l'échelle à une taille spécifiée. J'ai essayé plusieurs choses différentes, dont certaines peuvent être vues dans les lignes commentées. Je dois être en mesure de spécifier une hauteur et une largeur de l'image, soit en pouces ou en pixels, je ne me soucie pas nécessairement de qui, et avoir l'échelle xaml à cette taille pour le bitmap généré. Actuellement, si je rends la taille supérieure à la toile racine, le canevas est rendu à sa taille d'origine dans le coin supérieur gauche de l'image générée à la taille spécifiée. Voici la partie importante de mon httphandler. La toile racine stockée sous la forme "MyImage" a une hauteur de 600 et une largeur de 800. Que dois-je faire pour que le contenu s'adapte à la taille spécifiée?
Je ne comprends pas parfaitement ce que les dimensions passées dans Arrange() et Measure() font car une partie de ce code provient d'exemples en ligne. Je ne comprends pas complètement le truc de RenderTargetBitmap. Toute orientation serait appréciée.
Public Sub Capture(ByVal MyImage As Canvas)
' Determine the constraining scale to maintain the aspect ratio and the bounds of the image size
Dim scale As Double = Math.Min(Width/MyImage.Width, Height/MyImage.Height)
'Dim vbox As New Viewbox()
'vbox.Stretch = Stretch.Uniform
'vbox.StretchDirection = StretchDirection.Both
'vbox.Height = Height * scale * 300/96.0
'vbox.Width = Width * scale * 300/96.0
'vbox.Child = MyImage
Dim bounds As Rect = New Rect(0, 0, MyImage.Width * scale, MyImage.Height * scale)
MyImage.Measure(New Size(Width * scale, Height * scale))
MyImage.Arrange(bounds)
'MyImage.UpdateLayout()
' Create the target bitmap
Dim rtb As RenderTargetBitmap = New RenderTargetBitmap(CInt(Width * scale * 300/96.0), CInt(Height * scale * 300/96.0), 300, 300, PixelFormats.Pbgra32)
' Render the image to the target bitmap
Dim dv As DrawingVisual = New DrawingVisual()
Using ctx As DrawingContext = dv.RenderOpen()
Dim vb As New VisualBrush(MyImage)
'Dim vb As New VisualBrush(vbox)
ctx.DrawRectangle(vb, Nothing, New Rect(New System.Windows.Point(), bounds.Size))
End Using
rtb.Render(dv)
' Encode the image in the format selected
Dim encoder As System.Windows.Media.Imaging.BitmapEncoder
Select Case Encoding.ToLower
Case "jpg"
encoder = New System.Windows.Media.Imaging.JpegBitmapEncoder()
Case "png"
encoder = New System.Windows.Media.Imaging.PngBitmapEncoder()
Case "gif"
encoder = New System.Windows.Media.Imaging.GifBitmapEncoder()
Case "bmp"
encoder = New System.Windows.Media.Imaging.BmpBitmapEncoder()
Case "tif"
encoder = New System.Windows.Media.Imaging.TiffBitmapEncoder()
Case "wmp"
encoder = New System.Windows.Media.Imaging.WmpBitmapEncoder()
End Select
encoder.Frames.Add(System.Windows.Media.Imaging.BitmapFrame.Create(rtb))
' Create the memory stream to save the encoded image.
retImageStream = New System.IO.MemoryStream()
encoder.Save(retImageStream)
retImageStream.Flush()
retImageStream.Seek(0, System.IO.SeekOrigin.Begin)
MyImage = Nothing
End Sub
Cela a fini par me inspirer pour trouver la bonne solution si je l'ai marqué comme la réponse mais ci-dessous est le code qui a vraiment travaillé pour moi. –