Scaling WPF content before rendering to bitmap Scaling WPF content before rendering to bitmap wpf wpf

Scaling WPF content before rendering to bitmap


This should be enough to get you started:

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


This is what ended up working for me:

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