Справочная информация:
Я работаю над приложением silverlight (1.0), которое динамически создает карту Соединенных Штатов с наложенными в определенных местах значками и текстом. Карта отлично работает в браузере, и теперь мне нужно получить статическую (печатаемую и вставляемую в документы / powerpoints) копию отображаемой карты.
Цель:
Чтобы получить печатную копию карты, которая также может использоваться в слайдах PowerPoint, Word и т. Д. Я решил создать ASP.NET HttpHandler, чтобы воссоздать xaml на стороне сервера в WPF, а затем отобразить WPF в растровое изображение, которое возвращается в виде файла png, созданного с разрешением 300 точек на дюйм для лучшего качества печати.
Проблема:
Это прекрасно работает с одной проблемой, я не могу увеличить изображение до указанного размера. Я пробовал несколько разных вещей, некоторые из которых можно увидеть в закомментированных строках. Мне нужно иметь возможность указать высоту и ширину изображения, в дюймах или пикселях, мне не все равно, какое значение, и иметь масштаб xaml до этого размера для сгенерированного растрового изображения. В настоящее время, если я сделаю размер больше корневого холста, холст будет визуализирован с исходным размером в верхнем левом углу сгенерированного изображения с указанным размером. Ниже важная часть моего httphandler. Корневой холст, сохраненный как «MyImage», имеет высоту 600 и ширину 800. Чего мне не хватает, чтобы содержимое масштабировалось до указанного размера?
Я не совсем понимаю, что делают измерения, передаваемые в Arrange () и Measure (), так как часть этого кода была взята из онлайн-примеров. Я также не до конца понимаю материал RenderTargetBitmap. Любое руководство будет оценено.
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