Save a jpg image of my scene
Is it possible to save a jpg image of the a scene?
To render the 3D scene to a bitmap you can use the Camera.RenderToBitmap method to get a bitmap. You can specify many parameters (size of bitmap, DPI settings and anti-aliasing).

See the Utilities/RenderToBitmap sample in the Ab3d.PowerToys samples project:


The sample shows how to save to png file. To save to jpg file just replace the PngBitmapEncoder with the JpegBitmapEncoder (note that there you can also specify the QualityLevel) in the SaveBitmap method.

When using DXEngine to render the scene, then use DXViewportView.RenderToBitmap method instead of the method on Camera (see DXEngineOther/RenderToBitmap.xaml sample)
Andrej Benedik
Thanks!  I tried what you suggested and it worked great.

I'm using a button to save the image and it works well.  However, I have to add another related feature and I'm having some problems.

The scene has a building with several floors.  I need to save a separate image showing the building with just one floor, then 2 floors, then 3 floors, etc.  I need to do this automatically without having the user press a button for each floor.  I tried two different approaches and both failed.

First, I tried to just draw the image with one floor and immediately save the image.  I get the following error: "Cannot render to bitmap because TargetViewport3D is null"

Then, I figured I needed to wait for the image to be rendered, so I added a timer to wait a few seconds after I draw the image before I try to save it.  It does save without an error, but I get a blank jpg for all floors I'm trying to save.

Can you give me some advice on how to do what I need to do?
The "Cannot render to bitmap because TargetViewport3D is null" is thrown because the TargetViewport3D on the camera is not set. 

If you do not manually set the TargetViewport3D, then the code in the camera class tries to find the Viewport3D in the Loaded event. It is recommended to manually set the TargetViewport3D - this can be done in code or in XAML with using binding (for example: TargetViewport3D="{Binding ElementName=MainViewport}").

For a complete sample please check the RenderOfflineViewportButton_OnClick method in the RenderToBitmapSample sample in Ab3d.PowerToys samples project.

To make a simple demonstration on how to create a sequence of bitmaps with changes the camera and object, you can add the following code to the end of the RenderOfflineViewportButton_OnClick method:

           for (int i = 1; i < 5; i++)
               targetPositionCamera.Heading = i * 20;
               boxVisual3D.Transform = new ScaleTransform3D(1, (double)i / 4, 1);

               var bitmap = RenderToBitmap(targetPositionCamera);

               using (var fileStream = new FileStream($"c:\\temp\\bitmap_{i}.png", FileMode.Create))
                   BitmapEncoder encoder = new PngBitmapEncoder();

You will also need to update the RenderToBitmap to return BitmapSource object (and you can also comment calling the SaveBitmap method).

Note that this method renders does not render a teapot that is shown in the sample application but a custom 3D scene where the Viewport3D and its objects are created in code.
Andrej Benedik

Forum Jump:

Users browsing this thread:
1 Guest(s)