viewcomponent net mvc aspx asp asp.net wpf vb.net

asp.net - mvc - render partial asp net core



Escalar el contenido de WPF antes de renderizar en mapa de bits (2)

Esto debería ser suficiente para comenzar:

private void ExportCanvas(int width, int height) { string path = @"c:/temp/Test.tif"; FileStream fs = new FileStream(path, FileMode.Create); RenderTargetBitmap renderBitmap = new RenderTargetBitmap(width, height, 1/300, 1/300, PixelFormats.Pbgra32); DrawingVisual visual = new DrawingVisual(); using (DrawingContext context = visual.RenderOpen()) { VisualBrush brush = new VisualBrush(MyCanvas); context.DrawRectangle(brush, null, new Rect(new Point(), new Size(MyCanvas.Width, MyCanvas.Height))); } visual.Transform = new ScaleTransform(width / MyCanvas.ActualWidth, height / MyCanvas.ActualHeight); renderBitmap.Render(visual); BitmapEncoder encoder = new TiffBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(renderBitmap)); encoder.Save(fs); fs.Close(); }

Antecedentes: estoy trabajando en una aplicación Silverlight (1.0) que construye dinámicamente un mapa de los Estados Unidos con iconos y texto superpuestos en ubicaciones específicas. El mapa funciona muy bien en el navegador y ahora necesito obtener una copia estática (imprimible e insertable en documentos / powerpoints) de un mapa que se muestra.

Objetivo: Para obtener una copia imprimible del mapa que también se puede usar en diapositivas de PowerPoint, Word, etc., he elegido crear un ASP.NET HttpHandler para recrear el xaml en el lado del servidor en WPF y luego renderizar el WPF a una imagen de mapa de bits que se devuelve como un archivo png, generado a 300 ppp para una mejor calidad de impresión.

Problema: Esto funciona bien con un problema, no puedo hacer que la imagen se escale a un tamaño específico. Probé varias cosas diferentes, algunas de las cuales se pueden ver en las líneas comentadas. Necesito poder especificar el alto y el ancho de la imagen, ya sea en pulgadas o en píxeles, no me importa necesariamente cuál, y tengo la escala xaml para ese tamaño para el mapa de bits generado. Actualmente, si hago que el tamaño sea más grande que el lienzo raíz, el lienzo se procesa en su tamaño original en la esquina superior izquierda de la imagen generada en el tamaño especificado. A continuación se muestra la parte importante de mi httphandler. El lienzo raíz almacenado como "MyImage" tiene una Altura de 600 y un Ancho de 800. ¿Qué me falta para que el contenido se adapte al tamaño especificado?

No entiendo completamente qué hacen las dimensiones que pasan en Arrange () y Measure () ya que parte de este código fue tomado de ejemplos en línea. Tampoco entiendo completamente las cosas de RenderTargetBitmap. Cualquier orientación sería apreciada.

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


Esto es lo que terminó trabajando para mí:

Public Sub Capture(ByVal MyImage As Canvas) '' Normally we would obtain a user''s configured DPI setting to account for the possibilty of a high DPI setting. '' However, this code is running server side so the client''s DPI is not obtainable. Const SCREEN_DPI As Double = 96.0 '' Screen DPI Const TARGET_DPI As Double = 300.0 '' Print Quality DPI '' Determine the constraining scale to maintain the aspect ratio and the bounds of the image size Dim scale As Double = Math.Min(Width * SCREEN_DPI / MyImage.Width, Height * SCREEN_DPI / MyImage.Height) '' Setup the bounds of the image Dim bounds As Rect = New Rect(0, 0, MyImage.Width * scale, MyImage.Height * scale) MyImage.Measure(New Size(MyImage.Width * scale, MyImage.Height * scale)) MyImage.Arrange(bounds) '' Create the target bitmap Dim rtb As RenderTargetBitmap = New RenderTargetBitmap(CDbl(MyImage.Width * scale / SCREEN_DPI * TARGET_DPI), CDbl(MyImage.Height * scale / SCREEN_DPI * TARGET_DPI), TARGET_DPI, TARGET_DPI, 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) ctx.DrawRectangle(vb, Nothing, New Rect(New System.Windows.Point(), bounds.Size)) End Using '' Transform the visual to scale the image to our desired size. ''dv.Transform = New ScaleTransform(scale, scale) '' Render the visual to the bitmap. rtb.Render(dv) '' Encode the image in the format selected. If no valid format was selected, default to png. 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() Case Else encoder = New System.Windows.Media.Imaging.PngBitmapEncoder() 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