Question

Actually, I have to print the view from a Viewport3D, obviously, I use a RenderTargetBitmap. The problem is that if the resolution of the rendered image got high, some triangles of my scene don't appear on my final image.

For example, my viewport can be 1024*768 and the resolution I use with my RenderTargetBitmap would be 3 times viewport's resolution.

http://imgur.com/PS2F9D9

I already solved the problem in a certain way... In fact, triangles don't appear when I use a big scale. If I lower the size of my RenderTargetBitmap, it will contain everything.

Actually, I have more or less 1024*768 at 96dpi. If I want to impress at 300dpi, I need to get a huge image so I would like to avoid this last solution.

Some code :

public static RenderTargetBitmap CaptureEcran(Viewport3D p_viewPort, int p_scale)
    {
        RenderTargetBitmap l_bmp;
        p_scale = p_scale > 5 ? 5 : p_scale;
        l_bmp = new RenderTargetBitmap(p_scale * Convert.ToInt32(p_viewPort.ActualWidth), p_scale * Convert.ToInt32(p_viewPort.ActualHeight), p_scale * 96.0, p_scale * 96.0, PixelFormats.Pbgra32);

        DrawingVisual vis = new DrawingVisual();
        DrawingContext dc = vis.RenderOpen();
        dc.DrawRectangle(System.Windows.Media.Brushes.White, null, new Rect(0, 0, p_scale * p_viewPort.ActualWidth, p_scale * p_viewPort.ActualHeight));
        dc.Close();

        l_bmp.Render(vis);
        p_viewPort.UpdateLayout();
        l_bmp.Render(p_viewPort);
        return l_bmp;
    }

public static void SaveImage(RenderTargetBitmap renderTargetBitmap, string m_impression)
    {
        System.Windows.Forms.FolderBrowserDialog l_fBD = new System.Windows.Forms.FolderBrowserDialog();
        l_fBD.ShowDialog();
        string l_path = l_fBD.SelectedPath + "\\" + CurrentUser() + "__" + CurrentDate() + "__." + m_impression.ToLower();
        FileStream stream = new FileStream(l_path, FileMode.Create);

        BitmapEncoder l_encoder = null;
        switch(m_impression){
            case "PNG":
                PngBitmapEncoder l_png = new PngBitmapEncoder();
                l_encoder = l_png;
                break;
            case "JPEG":
                JpegBitmapEncoder l_jpeg = new JpegBitmapEncoder();
                l_jpeg.QualityLevel = 30;
                l_encoder = l_jpeg;
                break;
        }
        l_encoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
        l_encoder.Save(stream);
        stream.Close();
    }

My call is :

SaveImage(CaptureEcran(m_viewPortCourant.ViewPort3D,5), m_impression);

Where m_impression is .png or .jpg

Was it helpful?

Solution

It finally works by using a VisualBrush containing the viewport and drawn into the DrawingContext.

DrawingVisual vis = new DrawingVisual();
DrawingContext dc = vis.RenderOpen(); 
VisualBrush sourceBrush = new VisualBrush(p_viewPort);

dc.DrawRectangle(System.Windows.Media.Brushes.White, null, new Rect(0, 0, p_viewPort.ActualWidth * p_scale, p_viewPort.ActualHeight * p_scale));
dc.DrawRectangle(sourceBrush, null, new Rect(new System.Windows.Point(0, 0), new Vector(p_viewPort.ActualWidth, p_viewPort.ActualHeight)));
dc.Close();    

l_bmp.Render(vis);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top