asp.net - 在渲染为位图之前缩放 WPF 内容

标签 asp.net wpf vb.net

背景: 我正在开发一个 silverlight (1.0) 应用程序,该应用程序动态构建美国 map ,并在特定位置覆盖图标和文本。该 map 在浏览器中运行得很好,现在我需要获取所显示 map 的静态(可打印和可插入到文档/PowerPoint 中)副本。

目标: 为了获得也可以在 powerpoint 幻灯片、word 等中使用的 map 的可打印副本,我选择创建一个 ASP.NET HttpHandler 在 WPF 中的服务器端重新创建 xaml,然后将 WPF 渲染为以 png 文件形式返回的位图图像,以 300dpi 生成以获得更好的打印质量。

问题: 这对于解决一个问题非常有效,我无法将图像缩放到指定的大小。我尝试了几种不同的方法,其中一些可以在注释掉的行中看到。我需要能够指定图像的高度和宽度(以英寸或像素为单位),我不一定关心哪个,并且将 xaml 缩放到生成的位图的该大小。目前,如果我使尺寸大于根 Canvas ,则 Canvas 将以原始尺寸渲染在生成图像的左上角,并以指定的尺寸进行渲染。下面是我的 httphandler 的重要部分。存储为“MyImage”的根 Canvas 的高度为 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

最佳答案

这应该足以让您开始:


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();
}

关于asp.net - 在渲染为位图之前缩放 WPF 内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/222756/

相关文章:

c# - 两个验证组

c# - 将图像从浏览器拖放到 WPF 应用程序

c# - 在没有焦点的 WPF TextBox 中显示光标

javascript - 正则表达式模式不返回匹配项

vb.net - 以编程方式在 TabControl 中创建选项卡

vb.net - Designer.vb 页面和 .vb 页面有什么区别?

c# - 无法在 asp vNext 中修改 HttpResponse 对象上的原因短语

asp.net - 您使用什么方法将ASP.Net应用程序野外部署?

jquery - 使用 div 显示在两个选项卡/表格之间切换

wpf - 在 ViewModel 中捕获 CollectiveViewSource 的 Filter 事件