0

Odd problem, but I found that the RenderTargetBitmap function is rendering the margin to the left of the ViewPort3D. When I save the bitmap (PNG in this case), there's a gap on the left hand side of the final image and the right side is chopped off by the same amount. The dimensions of the ViewPort3D are 550px high by 1024px wide. I use the same dimensions in the RenderTargetBitmap method. I'm stumped as to why it's going outside the defined boundaries.

    <Grid>
    <Button Content="Save Snapshot" HorizontalAlignment="Left" Name="btnSaveSnapshot"  VerticalAlignment="Top" Width="100" Margin="8,8,0,0"/>
    <Viewport3D Name="vp3dTiles" Height="550" Width="1024" UseLayoutRounding="True"  HorizontalAlignment="Center" VerticalAlignment="Bottom" >
        <Viewport3D.Camera>
            <PerspectiveCamera Position="384,1750,174" LookDirection="0,-.65,-0.25"  UpDirection="0,0,1"  FieldOfView="65"/>
        </Viewport3D.Camera>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup>
                    <AmbientLight Color="white" />
                    <GeometryModel3D>
                        <GeometryModel3D.Geometry>
                            <MeshGeometry3D Positions="0,0,0 768,0,0 768,1408,0 0,1408,0 " TriangleIndices="0 1 3 1 2 3" TextureCoordinates="0,0 760,0 760,1408 0,1408 "/>                             
                        </GeometryModel3D.Geometry>
                        <GeometryModel3D.Material>                               
                            <DiffuseMaterial>
                                <DiffuseMaterial.Brush>
                                    <ImageBrush ViewportUnits="Absolute" TileMode="Tile" ImageSource="FlorVintage_FINAL.png" Viewport="0,0,768,1408" ViewboxUnits="Absolute" Stretch="None" AlignmentY="Top" RenderOptions.BitmapScalingMode="NearestNeighbor" AlignmentX="Left" />
                                </DiffuseMaterial.Brush> 
                            </DiffuseMaterial>
                        </GeometryModel3D.Material>

                    </GeometryModel3D>
                </Model3DGroup>
            </ModelVisual3D.Content>
        </ModelVisual3D>
    </Viewport3D>

</Grid>

And the code behind (in VB - sorry):

    Private Sub btnSaveSnapshot_Click(sender As Object, e As RoutedEventArgs) Handles btnSaveSnapshot.Click
    Dim bmp As New RenderTargetBitmap(1024, 550, 96, 96, PixelFormats.Pbgra32)
    bmp.Render(Me.vp3dTiles)
    Dim png As New PngBitmapEncoder()
    png.Frames.Add(BitmapFrame.Create(bmp))
    Using stm As Stream = File.Create(My.Settings.FileSavePath & "\" & "TestSnapshot.png")
        png.Save(stm)
    End Using
End Sub

I'm thinking it's the container that it is in (Grid) may be the problem.

MC9000
  • 2,076
  • 7
  • 45
  • 80

2 Answers2

0

I have one answer - define the grid rows and columns & set the column width to same as the ViewPort3D (there's only 1 column). I had to left-justify the grid in the window as well (go figure). Unfortunately, the ViewPort is aligned to the left - even though it is set to be centered - see code - this makes no sense, but I can deal with an ugly screen.

    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="40" ></RowDefinition>
        <RowDefinition Height="*"></RowDefinition>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="1024" MaxWidth="1024" MinWidth="1024"></ColumnDefinition>           
    </Grid.ColumnDefinitions>
    <Button Content="Save Snapshot" Grid.Row="0" HorizontalAlignment="Left" Name="btnSaveSnapshot"  VerticalAlignment="Top" Width="100" Margin="8,8,0,0"/>
    <Viewport3D Name="vp3dTiles"  Grid.Row="1" Height="550" Width="1024" UseLayoutRounding="True"  HorizontalAlignment="Center" VerticalAlignment="Bottom" >
        <Viewport3D.Camera>
            <PerspectiveCamera Position="384,1750,174" LookDirection="0,-.65,-0.25"  UpDirection="0,0,1"  FieldOfView="65"/>
        </Viewport3D.Camera>
        <ModelVisual3D>
            <ModelVisual3D.Content>
                <Model3DGroup>
                    <AmbientLight Color="white" />
                    <GeometryModel3D>
                        <GeometryModel3D.Geometry>
                            <MeshGeometry3D Positions="0,0,0 768,0,0 768,1408,0 0,1408,0 " TriangleIndices="0 1 3 1 2 3" TextureCoordinates="0,0 760,0 760,1408 0,1408 "/>                             
                        </GeometryModel3D.Geometry>
                        <GeometryModel3D.Material>                               
                            <DiffuseMaterial>
                                <DiffuseMaterial.Brush>
                                    <ImageBrush ViewportUnits="Absolute" TileMode="Tile" ImageSource="FlorVintage_FINAL.png" Viewport="0,0,768,1408" ViewboxUnits="Absolute" Stretch="None" AlignmentY="Top" RenderOptions.BitmapScalingMode="NearestNeighbor" AlignmentX="Left" />
                                </DiffuseMaterial.Brush> 
                            </DiffuseMaterial>
                        </GeometryModel3D.Material>

                    </GeometryModel3D>
                </Model3DGroup>
            </ModelVisual3D.Content>
        </ModelVisual3D>
    </Viewport3D>
    </Grid>
MC9000
  • 2,076
  • 7
  • 45
  • 80
0

When rendering, the visual size needs to match the render size and it needs to be updated. I use the following:

Dim imageWidth As Double = 2448
Dim imageHeight As Double = 2050
myviewport.Width = imageWidth / 2
myviewport.Height = imageHeight / 2
myviewport.Measure(New Size(imageWidth / 2, imageHeight / 2))
myviewport.Arrange(New Rect(0, 0, imageWidth / 2, imageHeight / 2))
'Capture Image here
myviewport.Width = Double.NaN 'restore previous value here
myviewport.Width = Double.NaN 'restore previous value here
VoteCoffee
  • 4,692
  • 1
  • 41
  • 44